0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 #ifndef _AIC79XX_LINUX_H_
0043 #define _AIC79XX_LINUX_H_
0044
0045 #include <linux/types.h>
0046 #include <linux/blkdev.h>
0047 #include <linux/delay.h>
0048 #include <linux/ioport.h>
0049 #include <linux/pci.h>
0050 #include <linux/interrupt.h>
0051 #include <linux/module.h>
0052 #include <linux/slab.h>
0053 #include <asm/byteorder.h>
0054 #include <asm/io.h>
0055
0056 #include <scsi/scsi.h>
0057 #include <scsi/scsi_cmnd.h>
0058 #include <scsi/scsi_eh.h>
0059 #include <scsi/scsi_device.h>
0060 #include <scsi/scsi_host.h>
0061 #include <scsi/scsi_tcq.h>
0062 #include <scsi/scsi_transport.h>
0063 #include <scsi/scsi_transport_spi.h>
0064
0065
0066 #define AIC_LIB_PREFIX ahd
0067
0068 #include "cam.h"
0069 #include "queue.h"
0070 #include "scsi_message.h"
0071 #include "scsi_iu.h"
0072 #include "aiclib.h"
0073
0074
0075 #ifdef CONFIG_AIC79XX_DEBUG_ENABLE
0076 #ifdef CONFIG_AIC79XX_DEBUG_MASK
0077 #define AHD_DEBUG 1
0078 #define AHD_DEBUG_OPTS CONFIG_AIC79XX_DEBUG_MASK
0079 #else
0080
0081
0082
0083 #define AHD_DEBUG 1
0084 #define AHD_DEBUG_OPTS 0
0085 #endif
0086
0087 #endif
0088
0089
0090 #define powerof2(x) ((((x)-1)&(x))==0)
0091
0092
0093 struct ahd_softc;
0094 typedef struct pci_dev *ahd_dev_softc_t;
0095 typedef struct scsi_cmnd *ahd_io_ctx_t;
0096
0097
0098 #define ahd_htobe16(x) cpu_to_be16(x)
0099 #define ahd_htobe32(x) cpu_to_be32(x)
0100 #define ahd_htobe64(x) cpu_to_be64(x)
0101 #define ahd_htole16(x) cpu_to_le16(x)
0102 #define ahd_htole32(x) cpu_to_le32(x)
0103 #define ahd_htole64(x) cpu_to_le64(x)
0104
0105 #define ahd_be16toh(x) be16_to_cpu(x)
0106 #define ahd_be32toh(x) be32_to_cpu(x)
0107 #define ahd_be64toh(x) be64_to_cpu(x)
0108 #define ahd_le16toh(x) le16_to_cpu(x)
0109 #define ahd_le32toh(x) le32_to_cpu(x)
0110 #define ahd_le64toh(x) le64_to_cpu(x)
0111
0112
0113 extern uint32_t aic79xx_allow_memio;
0114 extern struct scsi_host_template aic79xx_driver_template;
0115
0116
0117
0118 typedef uint32_t bus_size_t;
0119
0120 typedef enum {
0121 BUS_SPACE_MEMIO,
0122 BUS_SPACE_PIO
0123 } bus_space_tag_t;
0124
0125 typedef union {
0126 u_long ioport;
0127 volatile uint8_t __iomem *maddr;
0128 } bus_space_handle_t;
0129
0130 typedef struct bus_dma_segment
0131 {
0132 dma_addr_t ds_addr;
0133 bus_size_t ds_len;
0134 } bus_dma_segment_t;
0135
0136 struct ahd_linux_dma_tag
0137 {
0138 bus_size_t alignment;
0139 bus_size_t boundary;
0140 bus_size_t maxsize;
0141 };
0142 typedef struct ahd_linux_dma_tag* bus_dma_tag_t;
0143
0144 typedef dma_addr_t bus_dmamap_t;
0145
0146 typedef int bus_dma_filter_t(void*, dma_addr_t);
0147 typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
0148
0149 #define BUS_DMA_WAITOK 0x0
0150 #define BUS_DMA_NOWAIT 0x1
0151 #define BUS_DMA_ALLOCNOW 0x2
0152 #define BUS_DMA_LOAD_SEGS 0x4
0153
0154
0155
0156
0157 #define BUS_SPACE_MAXADDR 0xFFFFFFFF
0158 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
0159 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
0160
0161 int ahd_dma_tag_create(struct ahd_softc *, bus_dma_tag_t ,
0162 bus_size_t , bus_size_t ,
0163 dma_addr_t , dma_addr_t ,
0164 bus_dma_filter_t*, void *,
0165 bus_size_t , int ,
0166 bus_size_t , int ,
0167 bus_dma_tag_t *);
0168
0169 void ahd_dma_tag_destroy(struct ahd_softc *, bus_dma_tag_t );
0170
0171 int ahd_dmamem_alloc(struct ahd_softc *, bus_dma_tag_t ,
0172 void** , int ,
0173 bus_dmamap_t* );
0174
0175 void ahd_dmamem_free(struct ahd_softc *, bus_dma_tag_t ,
0176 void* , bus_dmamap_t );
0177
0178 void ahd_dmamap_destroy(struct ahd_softc *, bus_dma_tag_t ,
0179 bus_dmamap_t );
0180
0181 int ahd_dmamap_load(struct ahd_softc *ahd, bus_dma_tag_t ,
0182 bus_dmamap_t , void * ,
0183 bus_size_t , bus_dmamap_callback_t *,
0184 void *, int );
0185
0186 int ahd_dmamap_unload(struct ahd_softc *, bus_dma_tag_t, bus_dmamap_t);
0187
0188
0189
0190
0191 #define BUS_DMASYNC_PREREAD 0x01
0192 #define BUS_DMASYNC_POSTREAD 0x02
0193 #define BUS_DMASYNC_PREWRITE 0x04
0194 #define BUS_DMASYNC_POSTWRITE 0x08
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204 #define ahd_dmamap_sync(ahd, dma_tag, dmamap, offset, len, op)
0205
0206
0207 #ifdef CONFIG_AIC79XX_REG_PRETTY_PRINT
0208 #define AIC_DEBUG_REGISTERS 1
0209 #else
0210 #define AIC_DEBUG_REGISTERS 0
0211 #endif
0212 #include "aic79xx.h"
0213
0214
0215 #include <linux/spinlock.h>
0216
0217 #define AIC79XX_DRIVER_VERSION "3.0"
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228 typedef enum {
0229 AHD_DEV_FREEZE_TIL_EMPTY = 0x02,
0230 AHD_DEV_Q_BASIC = 0x10,
0231 AHD_DEV_Q_TAGGED = 0x20,
0232 AHD_DEV_PERIODIC_OTAG = 0x40,
0233 } ahd_linux_dev_flags;
0234
0235 struct ahd_linux_device {
0236 TAILQ_ENTRY(ahd_linux_device) links;
0237
0238
0239
0240
0241
0242 int active;
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252 int openings;
0253
0254
0255
0256
0257
0258 u_int qfrozen;
0259
0260
0261
0262
0263 u_long commands_issued;
0264
0265
0266
0267
0268
0269
0270
0271 u_int tag_success_count;
0272 #define AHD_TAG_SUCCESS_INTERVAL 50
0273
0274 ahd_linux_dev_flags flags;
0275
0276
0277
0278
0279 struct timer_list timer;
0280
0281
0282
0283
0284 u_int maxtags;
0285
0286
0287
0288
0289
0290 u_int tags_on_last_queuefull;
0291
0292
0293
0294
0295
0296
0297
0298 u_int last_queuefull_same_count;
0299 #define AHD_LOCK_TAGS_COUNT 50
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310 u_int commands_since_idle_or_otag;
0311 #define AHD_OTAG_THRESH 500
0312 };
0313
0314
0315
0316
0317
0318
0319
0320
0321 #define AHD_NSEG 128
0322
0323
0324
0325
0326 struct scb_platform_data {
0327 struct ahd_linux_device *dev;
0328 dma_addr_t buf_busaddr;
0329 uint32_t xfer_len;
0330 uint32_t sense_resid;
0331 };
0332
0333
0334
0335
0336
0337
0338
0339 struct ahd_platform_data {
0340
0341
0342
0343 struct scsi_target *starget[AHD_NUM_TARGETS];
0344
0345 spinlock_t spin_lock;
0346 struct completion *eh_done;
0347 struct Scsi_Host *host;
0348 #define AHD_LINUX_NOIRQ ((uint32_t)~0)
0349 uint32_t irq;
0350 uint32_t bios_address;
0351 resource_size_t mem_busaddr;
0352 };
0353
0354 void ahd_delay(long);
0355
0356
0357 uint8_t ahd_inb(struct ahd_softc * ahd, long port);
0358 void ahd_outb(struct ahd_softc * ahd, long port, uint8_t val);
0359 void ahd_outw_atomic(struct ahd_softc * ahd,
0360 long port, uint16_t val);
0361 void ahd_outsb(struct ahd_softc * ahd, long port,
0362 uint8_t *, int count);
0363 void ahd_insb(struct ahd_softc * ahd, long port,
0364 uint8_t *, int count);
0365
0366
0367 int ahd_linux_register_host(struct ahd_softc *,
0368 struct scsi_host_template *);
0369
0370
0371 static inline void
0372 ahd_lockinit(struct ahd_softc *ahd)
0373 {
0374 spin_lock_init(&ahd->platform_data->spin_lock);
0375 }
0376
0377 static inline void
0378 ahd_lock(struct ahd_softc *ahd, unsigned long *flags)
0379 {
0380 spin_lock_irqsave(&ahd->platform_data->spin_lock, *flags);
0381 }
0382
0383 static inline void
0384 ahd_unlock(struct ahd_softc *ahd, unsigned long *flags)
0385 {
0386 spin_unlock_irqrestore(&ahd->platform_data->spin_lock, *flags);
0387 }
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399 #define PCIR_DEVVENDOR 0x00
0400 #define PCIR_VENDOR 0x00
0401 #define PCIR_DEVICE 0x02
0402 #define PCIR_COMMAND 0x04
0403 #define PCIM_CMD_PORTEN 0x0001
0404 #define PCIM_CMD_MEMEN 0x0002
0405 #define PCIM_CMD_BUSMASTEREN 0x0004
0406 #define PCIM_CMD_MWRICEN 0x0010
0407 #define PCIM_CMD_PERRESPEN 0x0040
0408 #define PCIM_CMD_SERRESPEN 0x0100
0409 #define PCIR_STATUS 0x06
0410 #define PCIR_REVID 0x08
0411 #define PCIR_PROGIF 0x09
0412 #define PCIR_SUBCLASS 0x0a
0413 #define PCIR_CLASS 0x0b
0414 #define PCIR_CACHELNSZ 0x0c
0415 #define PCIR_LATTIMER 0x0d
0416 #define PCIR_HEADERTYPE 0x0e
0417 #define PCIM_MFDEV 0x80
0418 #define PCIR_BIST 0x0f
0419 #define PCIR_CAP_PTR 0x34
0420
0421
0422 #define PCIR_MAPS 0x10
0423
0424
0425 #define PCIXR_COMMAND 0x96
0426 #define PCIXR_DEVADDR 0x98
0427 #define PCIXM_DEVADDR_FNUM 0x0003
0428 #define PCIXM_DEVADDR_DNUM 0x00F8
0429 #define PCIXM_DEVADDR_BNUM 0xFF00
0430 #define PCIXR_STATUS 0x9A
0431 #define PCIXM_STATUS_64BIT 0x0001
0432 #define PCIXM_STATUS_133CAP 0x0002
0433 #define PCIXM_STATUS_SCDISC 0x0004
0434 #define PCIXM_STATUS_UNEXPSC 0x0008
0435 #define PCIXM_STATUS_CMPLEXDEV 0x0010
0436 #define PCIXM_STATUS_MAXMRDBC 0x0060
0437 #define PCIXM_STATUS_MAXSPLITS 0x0380
0438 #define PCIXM_STATUS_MAXCRDS 0x1C00
0439 #define PCIXM_STATUS_RCVDSCEM 0x2000
0440
0441 typedef enum
0442 {
0443 AHD_POWER_STATE_D0,
0444 AHD_POWER_STATE_D1,
0445 AHD_POWER_STATE_D2,
0446 AHD_POWER_STATE_D3
0447 } ahd_power_state;
0448
0449 void ahd_power_state_change(struct ahd_softc *ahd,
0450 ahd_power_state new_state);
0451
0452
0453 int ahd_linux_pci_init(void);
0454 void ahd_linux_pci_exit(void);
0455 int ahd_pci_map_registers(struct ahd_softc *ahd);
0456 int ahd_pci_map_int(struct ahd_softc *ahd);
0457
0458 uint32_t ahd_pci_read_config(ahd_dev_softc_t pci,
0459 int reg, int width);
0460 void ahd_pci_write_config(ahd_dev_softc_t pci,
0461 int reg, uint32_t value,
0462 int width);
0463
0464 static inline int ahd_get_pci_function(ahd_dev_softc_t);
0465 static inline int
0466 ahd_get_pci_function(ahd_dev_softc_t pci)
0467 {
0468 return (PCI_FUNC(pci->devfn));
0469 }
0470
0471 static inline int ahd_get_pci_slot(ahd_dev_softc_t);
0472 static inline int
0473 ahd_get_pci_slot(ahd_dev_softc_t pci)
0474 {
0475 return (PCI_SLOT(pci->devfn));
0476 }
0477
0478 static inline int ahd_get_pci_bus(ahd_dev_softc_t);
0479 static inline int
0480 ahd_get_pci_bus(ahd_dev_softc_t pci)
0481 {
0482 return (pci->bus->number);
0483 }
0484
0485 static inline void ahd_flush_device_writes(struct ahd_softc *);
0486 static inline void
0487 ahd_flush_device_writes(struct ahd_softc *ahd)
0488 {
0489
0490 ahd_inb(ahd, INTSTAT);
0491 }
0492
0493
0494 int ahd_proc_write_seeprom(struct Scsi_Host *, char *, int);
0495 int ahd_linux_show_info(struct seq_file *,struct Scsi_Host *);
0496
0497
0498
0499 static inline
0500 void ahd_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status)
0501 {
0502 cmd->result &= ~(CAM_STATUS_MASK << 16);
0503 cmd->result |= status << 16;
0504 }
0505
0506 static inline
0507 void ahd_set_transaction_status(struct scb *scb, uint32_t status)
0508 {
0509 ahd_cmd_set_transaction_status(scb->io_ctx,status);
0510 }
0511
0512 static inline
0513 void ahd_cmd_set_scsi_status(struct scsi_cmnd *cmd, uint32_t status)
0514 {
0515 cmd->result &= ~0xFFFF;
0516 cmd->result |= status;
0517 }
0518
0519 static inline
0520 void ahd_set_scsi_status(struct scb *scb, uint32_t status)
0521 {
0522 ahd_cmd_set_scsi_status(scb->io_ctx, status);
0523 }
0524
0525 static inline
0526 uint32_t ahd_cmd_get_transaction_status(struct scsi_cmnd *cmd)
0527 {
0528 return ((cmd->result >> 16) & CAM_STATUS_MASK);
0529 }
0530
0531 static inline
0532 uint32_t ahd_get_transaction_status(struct scb *scb)
0533 {
0534 return (ahd_cmd_get_transaction_status(scb->io_ctx));
0535 }
0536
0537 static inline
0538 uint32_t ahd_cmd_get_scsi_status(struct scsi_cmnd *cmd)
0539 {
0540 return (cmd->result & 0xFFFF);
0541 }
0542
0543 static inline
0544 uint32_t ahd_get_scsi_status(struct scb *scb)
0545 {
0546 return (ahd_cmd_get_scsi_status(scb->io_ctx));
0547 }
0548
0549 static inline
0550 void ahd_set_transaction_tag(struct scb *scb, int enabled, u_int type)
0551 {
0552
0553
0554
0555
0556 }
0557
0558 static inline
0559 u_long ahd_get_transfer_length(struct scb *scb)
0560 {
0561 return (scb->platform_data->xfer_len);
0562 }
0563
0564 static inline
0565 int ahd_get_transfer_dir(struct scb *scb)
0566 {
0567 return (scb->io_ctx->sc_data_direction);
0568 }
0569
0570 static inline
0571 void ahd_set_residual(struct scb *scb, u_long resid)
0572 {
0573 scsi_set_resid(scb->io_ctx, resid);
0574 }
0575
0576 static inline
0577 void ahd_set_sense_residual(struct scb *scb, u_long resid)
0578 {
0579 scb->platform_data->sense_resid = resid;
0580 }
0581
0582 static inline
0583 u_long ahd_get_residual(struct scb *scb)
0584 {
0585 return scsi_get_resid(scb->io_ctx);
0586 }
0587
0588 static inline
0589 u_long ahd_get_sense_residual(struct scb *scb)
0590 {
0591 return (scb->platform_data->sense_resid);
0592 }
0593
0594 static inline
0595 int ahd_perform_autosense(struct scb *scb)
0596 {
0597
0598
0599
0600
0601
0602 return (1);
0603 }
0604
0605 static inline uint32_t
0606 ahd_get_sense_bufsize(struct ahd_softc *ahd, struct scb *scb)
0607 {
0608 return (sizeof(struct scsi_sense_data));
0609 }
0610
0611 static inline void
0612 ahd_notify_xfer_settings_change(struct ahd_softc *ahd,
0613 struct ahd_devinfo *devinfo)
0614 {
0615
0616 }
0617
0618 static inline void
0619 ahd_platform_scb_free(struct ahd_softc *ahd, struct scb *scb)
0620 {
0621 ahd->flags &= ~AHD_RESOURCE_SHORTAGE;
0622 }
0623
0624 int ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg);
0625 void ahd_platform_free(struct ahd_softc *ahd);
0626 void ahd_platform_init(struct ahd_softc *ahd);
0627 void ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb);
0628
0629 static inline void
0630 ahd_freeze_scb(struct scb *scb)
0631 {
0632 if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) {
0633 scb->io_ctx->result |= CAM_DEV_QFRZN << 16;
0634 scb->platform_data->dev->qfrozen++;
0635 }
0636 }
0637
0638 void ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev,
0639 struct ahd_devinfo *devinfo, ahd_queue_alg);
0640 int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target,
0641 char channel, int lun, u_int tag,
0642 role_t role, uint32_t status);
0643 irqreturn_t
0644 ahd_linux_isr(int irq, void *dev_id);
0645 void ahd_done(struct ahd_softc*, struct scb*);
0646 void ahd_send_async(struct ahd_softc *, char channel,
0647 u_int target, u_int lun, ac_code);
0648 void ahd_print_path(struct ahd_softc *, struct scb *);
0649
0650 #ifdef CONFIG_PCI
0651 #define AHD_PCI_CONFIG 1
0652 #else
0653 #define AHD_PCI_CONFIG 0
0654 #endif
0655 #define bootverbose aic79xx_verbose
0656 extern uint32_t aic79xx_verbose;
0657
0658 #endif