From 3d0e63754fa47d65edff172c1156f44b6fca5ca1 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 6 Aug 2018 16:32:16 -0700 Subject: drbd: Convert from ahash to shash In preparing to remove all stack VLA usage from the kernel[1], this removes the discouraged use of AHASH_REQUEST_ON_STACK in favor of the smaller SHASH_DESC_ON_STACK by converting from ahash-wrapped-shash to direct shash. By removing a layer of indirection this both improves performance and reduces stack usage. The stack allocation will be made a fixed size in a later patch to the crypto subsystem. The bulk of the lines in this change are simple s/ahash/shash/, but the main logic differences are in drbd_csum_ee() and drbd_csum_bio(), which externalizes the page walking with k(un)map_atomic() instead of using scattergather. [1] https://lkml.kernel.org/r/CA+55aFzCG-zNmZwX4A2FQpadafLfEzK6CC=qPXydAacU1RqZWA@mail.gmail.com Acked-by: Lars Ellenberg Signed-off-by: Kees Cook Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_int.h | 13 ++++---- drivers/block/drbd/drbd_main.c | 14 ++++----- drivers/block/drbd/drbd_nl.c | 39 ++++++++--------------- drivers/block/drbd/drbd_receiver.c | 35 +++++++++++---------- drivers/block/drbd/drbd_worker.c | 63 +++++++++++++++++++------------------- 5 files changed, 76 insertions(+), 88 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index e35a234b0a8f..8a4c1328e6f9 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -724,10 +724,10 @@ struct drbd_connection { struct list_head transfer_log; /* all requests not yet fully processed */ struct crypto_shash *cram_hmac_tfm; - struct crypto_ahash *integrity_tfm; /* checksums we compute, updates protected by connection->data->mutex */ - struct crypto_ahash *peer_integrity_tfm; /* checksums we verify, only accessed from receiver thread */ - struct crypto_ahash *csums_tfm; - struct crypto_ahash *verify_tfm; + struct crypto_shash *integrity_tfm; /* checksums we compute, updates protected by connection->data->mutex */ + struct crypto_shash *peer_integrity_tfm; /* checksums we verify, only accessed from receiver thread */ + struct crypto_shash *csums_tfm; + struct crypto_shash *verify_tfm; void *int_dig_in; void *int_dig_vv; @@ -1531,8 +1531,9 @@ static inline void ov_out_of_sync_print(struct drbd_device *device) } -extern void drbd_csum_bio(struct crypto_ahash *, struct bio *, void *); -extern void drbd_csum_ee(struct crypto_ahash *, struct drbd_peer_request *, void *); +extern void drbd_csum_bio(struct crypto_shash *, struct bio *, void *); +extern void drbd_csum_ee(struct crypto_shash *, struct drbd_peer_request *, + void *); /* worker callbacks */ extern int w_e_end_data_req(struct drbd_work *, int); extern int w_e_end_rsdata_req(struct drbd_work *, int); diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index ef8212a4b73e..15a9ffce9012 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -1377,7 +1377,7 @@ void drbd_send_ack_dp(struct drbd_peer_device *peer_device, enum drbd_packet cmd struct p_data *dp, int data_size) { if (peer_device->connection->peer_integrity_tfm) - data_size -= crypto_ahash_digestsize(peer_device->connection->peer_integrity_tfm); + data_size -= crypto_shash_digestsize(peer_device->connection->peer_integrity_tfm); _drbd_send_ack(peer_device, cmd, dp->sector, cpu_to_be32(data_size), dp->block_id); } @@ -1690,7 +1690,7 @@ int drbd_send_dblock(struct drbd_peer_device *peer_device, struct drbd_request * sock = &peer_device->connection->data; p = drbd_prepare_command(peer_device, sock); digest_size = peer_device->connection->integrity_tfm ? - crypto_ahash_digestsize(peer_device->connection->integrity_tfm) : 0; + crypto_shash_digestsize(peer_device->connection->integrity_tfm) : 0; if (!p) return -EIO; @@ -1796,7 +1796,7 @@ int drbd_send_block(struct drbd_peer_device *peer_device, enum drbd_packet cmd, p = drbd_prepare_command(peer_device, sock); digest_size = peer_device->connection->integrity_tfm ? - crypto_ahash_digestsize(peer_device->connection->integrity_tfm) : 0; + crypto_shash_digestsize(peer_device->connection->integrity_tfm) : 0; if (!p) return -EIO; @@ -2557,11 +2557,11 @@ void conn_free_crypto(struct drbd_connection *connection) { drbd_free_sock(connection); - crypto_free_ahash(connection->csums_tfm); - crypto_free_ahash(connection->verify_tfm); + crypto_free_shash(connection->csums_tfm); + crypto_free_shash(connection->verify_tfm); crypto_free_shash(connection->cram_hmac_tfm); - crypto_free_ahash(connection->integrity_tfm); - crypto_free_ahash(connection->peer_integrity_tfm); + crypto_free_shash(connection->integrity_tfm); + crypto_free_shash(connection->peer_integrity_tfm); kfree(connection->int_dig_in); kfree(connection->int_dig_vv); diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index b4f02768ba47..d15703b1ffe8 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -2303,10 +2303,10 @@ check_net_options(struct drbd_connection *connection, struct net_conf *new_net_c } struct crypto { - struct crypto_ahash *verify_tfm; - struct crypto_ahash *csums_tfm; + struct crypto_shash *verify_tfm; + struct crypto_shash *csums_tfm; struct crypto_shash *cram_hmac_tfm; - struct crypto_ahash *integrity_tfm; + struct crypto_shash *integrity_tfm; }; static int @@ -2324,36 +2324,21 @@ alloc_shash(struct crypto_shash **tfm, char *tfm_name, int err_alg) return NO_ERROR; } -static int -alloc_ahash(struct crypto_ahash **tfm, char *tfm_name, int err_alg) -{ - if (!tfm_name[0]) - return NO_ERROR; - - *tfm = crypto_alloc_ahash(tfm_name, 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(*tfm)) { - *tfm = NULL; - return err_alg; - } - - return NO_ERROR; -} - static enum drbd_ret_code alloc_crypto(struct crypto *crypto, struct net_conf *new_net_conf) { char hmac_name[CRYPTO_MAX_ALG_NAME]; enum drbd_ret_code rv; - rv = alloc_ahash(&crypto->csums_tfm, new_net_conf->csums_alg, + rv = alloc_shash(&crypto->csums_tfm, new_net_conf->csums_alg, ERR_CSUMS_ALG); if (rv != NO_ERROR) return rv; - rv = alloc_ahash(&crypto->verify_tfm, new_net_conf->verify_alg, + rv = alloc_shash(&crypto->verify_tfm, new_net_conf->verify_alg, ERR_VERIFY_ALG); if (rv != NO_ERROR) return rv; - rv = alloc_ahash(&crypto->integrity_tfm, new_net_conf->integrity_alg, + rv = alloc_shash(&crypto->integrity_tfm, new_net_conf->integrity_alg, ERR_INTEGRITY_ALG); if (rv != NO_ERROR) return rv; @@ -2371,9 +2356,9 @@ alloc_crypto(struct crypto *crypto, struct net_conf *new_net_conf) static void free_crypto(struct crypto *crypto) { crypto_free_shash(crypto->cram_hmac_tfm); - crypto_free_ahash(crypto->integrity_tfm); - crypto_free_ahash(crypto->csums_tfm); - crypto_free_ahash(crypto->verify_tfm); + crypto_free_shash(crypto->integrity_tfm); + crypto_free_shash(crypto->csums_tfm); + crypto_free_shash(crypto->verify_tfm); } int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info) @@ -2450,17 +2435,17 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info) rcu_assign_pointer(connection->net_conf, new_net_conf); if (!rsr) { - crypto_free_ahash(connection->csums_tfm); + crypto_free_shash(connection->csums_tfm); connection->csums_tfm = crypto.csums_tfm; crypto.csums_tfm = NULL; } if (!ovr) { - crypto_free_ahash(connection->verify_tfm); + crypto_free_shash(connection->verify_tfm); connection->verify_tfm = crypto.verify_tfm; crypto.verify_tfm = NULL; } - crypto_free_ahash(connection->integrity_tfm); + crypto_free_shash(connection->integrity_tfm); connection->integrity_tfm = crypto.integrity_tfm; if (connection->cstate >= C_WF_REPORT_PARAMS && connection->agreed_pro_version >= 100) /* Do this without trying to take connection->data.mutex again. */ diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 75f6b47169e6..fc67fd853375 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -1732,7 +1732,7 @@ static int receive_Barrier(struct drbd_connection *connection, struct packet_inf } /* quick wrapper in case payload size != request_size (write same) */ -static void drbd_csum_ee_size(struct crypto_ahash *h, +static void drbd_csum_ee_size(struct crypto_shash *h, struct drbd_peer_request *r, void *d, unsigned int payload_size) { @@ -1769,7 +1769,7 @@ read_in_block(struct drbd_peer_device *peer_device, u64 id, sector_t sector, digest_size = 0; if (!trim && peer_device->connection->peer_integrity_tfm) { - digest_size = crypto_ahash_digestsize(peer_device->connection->peer_integrity_tfm); + digest_size = crypto_shash_digestsize(peer_device->connection->peer_integrity_tfm); /* * FIXME: Receive the incoming digest into the receive buffer * here, together with its struct p_data? @@ -1905,7 +1905,7 @@ static int recv_dless_read(struct drbd_peer_device *peer_device, struct drbd_req digest_size = 0; if (peer_device->connection->peer_integrity_tfm) { - digest_size = crypto_ahash_digestsize(peer_device->connection->peer_integrity_tfm); + digest_size = crypto_shash_digestsize(peer_device->connection->peer_integrity_tfm); err = drbd_recv_all_warn(peer_device->connection, dig_in, digest_size); if (err) return err; @@ -3542,7 +3542,7 @@ static int receive_protocol(struct drbd_connection *connection, struct packet_in int p_proto, p_discard_my_data, p_two_primaries, cf; struct net_conf *nc, *old_net_conf, *new_net_conf = NULL; char integrity_alg[SHARED_SECRET_MAX] = ""; - struct crypto_ahash *peer_integrity_tfm = NULL; + struct crypto_shash *peer_integrity_tfm = NULL; void *int_dig_in = NULL, *int_dig_vv = NULL; p_proto = be32_to_cpu(p->protocol); @@ -3623,7 +3623,7 @@ static int receive_protocol(struct drbd_connection *connection, struct packet_in * change. */ - peer_integrity_tfm = crypto_alloc_ahash(integrity_alg, 0, CRYPTO_ALG_ASYNC); + peer_integrity_tfm = crypto_alloc_shash(integrity_alg, 0, CRYPTO_ALG_ASYNC); if (IS_ERR(peer_integrity_tfm)) { peer_integrity_tfm = NULL; drbd_err(connection, "peer data-integrity-alg %s not supported\n", @@ -3631,7 +3631,7 @@ static int receive_protocol(struct drbd_connection *connection, struct packet_in goto disconnect; } - hash_size = crypto_ahash_digestsize(peer_integrity_tfm); + hash_size = crypto_shash_digestsize(peer_integrity_tfm); int_dig_in = kmalloc(hash_size, GFP_KERNEL); int_dig_vv = kmalloc(hash_size, GFP_KERNEL); if (!(int_dig_in && int_dig_vv)) { @@ -3661,7 +3661,7 @@ static int receive_protocol(struct drbd_connection *connection, struct packet_in mutex_unlock(&connection->resource->conf_update); mutex_unlock(&connection->data.mutex); - crypto_free_ahash(connection->peer_integrity_tfm); + crypto_free_shash(connection->peer_integrity_tfm); kfree(connection->int_dig_in); kfree(connection->int_dig_vv); connection->peer_integrity_tfm = peer_integrity_tfm; @@ -3679,7 +3679,7 @@ static int receive_protocol(struct drbd_connection *connection, struct packet_in disconnect_rcu_unlock: rcu_read_unlock(); disconnect: - crypto_free_ahash(peer_integrity_tfm); + crypto_free_shash(peer_integrity_tfm); kfree(int_dig_in); kfree(int_dig_vv); conn_request_state(connection, NS(conn, C_DISCONNECTING), CS_HARD); @@ -3691,15 +3691,16 @@ disconnect: * return: NULL (alg name was "") * ERR_PTR(error) if something goes wrong * or the crypto hash ptr, if it worked out ok. */ -static struct crypto_ahash *drbd_crypto_alloc_digest_safe(const struct drbd_device *device, +static struct crypto_shash *drbd_crypto_alloc_digest_safe( + const struct drbd_device *device, const char *alg, const char *name) { - struct crypto_ahash *tfm; + struct crypto_shash *tfm; if (!alg[0]) return NULL; - tfm = crypto_alloc_ahash(alg, 0, CRYPTO_ALG_ASYNC); + tfm = crypto_alloc_shash(alg, 0, 0); if (IS_ERR(tfm)) { drbd_err(device, "Can not allocate \"%s\" as %s (reason: %ld)\n", alg, name, PTR_ERR(tfm)); @@ -3752,8 +3753,8 @@ static int receive_SyncParam(struct drbd_connection *connection, struct packet_i struct drbd_device *device; struct p_rs_param_95 *p; unsigned int header_size, data_size, exp_max_sz; - struct crypto_ahash *verify_tfm = NULL; - struct crypto_ahash *csums_tfm = NULL; + struct crypto_shash *verify_tfm = NULL; + struct crypto_shash *csums_tfm = NULL; struct net_conf *old_net_conf, *new_net_conf = NULL; struct disk_conf *old_disk_conf = NULL, *new_disk_conf = NULL; const int apv = connection->agreed_pro_version; @@ -3900,14 +3901,14 @@ static int receive_SyncParam(struct drbd_connection *connection, struct packet_i if (verify_tfm) { strcpy(new_net_conf->verify_alg, p->verify_alg); new_net_conf->verify_alg_len = strlen(p->verify_alg) + 1; - crypto_free_ahash(peer_device->connection->verify_tfm); + crypto_free_shash(peer_device->connection->verify_tfm); peer_device->connection->verify_tfm = verify_tfm; drbd_info(device, "using verify-alg: \"%s\"\n", p->verify_alg); } if (csums_tfm) { strcpy(new_net_conf->csums_alg, p->csums_alg); new_net_conf->csums_alg_len = strlen(p->csums_alg) + 1; - crypto_free_ahash(peer_device->connection->csums_tfm); + crypto_free_shash(peer_device->connection->csums_tfm); peer_device->connection->csums_tfm = csums_tfm; drbd_info(device, "using csums-alg: \"%s\"\n", p->csums_alg); } @@ -3951,9 +3952,9 @@ disconnect: mutex_unlock(&connection->resource->conf_update); /* just for completeness: actually not needed, * as this is not reached if csums_tfm was ok. */ - crypto_free_ahash(csums_tfm); + crypto_free_shash(csums_tfm); /* but free the verify_tfm again, if csums_tfm did not work out */ - crypto_free_ahash(verify_tfm); + crypto_free_shash(verify_tfm); conn_request_state(peer_device->connection, NS(conn, C_DISCONNECTING), CS_HARD); return -EIO; } diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index b8f77e83d456..c7ef48efe871 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -295,60 +295,61 @@ void drbd_request_endio(struct bio *bio) complete_master_bio(device, &m); } -void drbd_csum_ee(struct crypto_ahash *tfm, struct drbd_peer_request *peer_req, void *digest) +void drbd_csum_ee(struct crypto_shash *tfm, struct drbd_peer_request *peer_req, void *digest) { - AHASH_REQUEST_ON_STACK(req, tfm); - struct scatterlist sg; + SHASH_DESC_ON_STACK(desc, tfm); struct page *page = peer_req->pages; struct page *tmp; unsigned len; + void *src; - ahash_request_set_tfm(req, tfm); - ahash_request_set_callback(req, 0, NULL, NULL); + desc->tfm = tfm; + desc->flags = 0; - sg_init_table(&sg, 1); - crypto_ahash_init(req); + crypto_shash_init(desc); + src = kmap_atomic(page); while ((tmp = page_chain_next(page))) { /* all but the last page will be fully used */ - sg_set_page(&sg, page, PAGE_SIZE, 0); - ahash_request_set_crypt(req, &sg, NULL, sg.length); - crypto_ahash_update(req); + crypto_shash_update(desc, src, PAGE_SIZE); + kunmap_atomic(src); page = tmp; + src = kmap_atomic(page); } /* and now the last, possibly only partially used page */ len = peer_req->i.size & (PAGE_SIZE - 1); - sg_set_page(&sg, page, len ?: PAGE_SIZE, 0); - ahash_request_set_crypt(req, &sg, digest, sg.length); - crypto_ahash_finup(req); - ahash_request_zero(req); + crypto_shash_update(desc, src, len ?: PAGE_SIZE); + kunmap_atomic(src); + + crypto_shash_final(desc, digest); + shash_desc_zero(desc); } -void drbd_csum_bio(struct crypto_ahash *tfm, struct bio *bio, void *digest) +void drbd_csum_bio(struct crypto_shash *tfm, struct bio *bio, void *digest) { - AHASH_REQUEST_ON_STACK(req, tfm); - struct scatterlist sg; + SHASH_DESC_ON_STACK(desc, tfm); struct bio_vec bvec; struct bvec_iter iter; - ahash_request_set_tfm(req, tfm); - ahash_request_set_callback(req, 0, NULL, NULL); + desc->tfm = tfm; + desc->flags = 0; - sg_init_table(&sg, 1); - crypto_ahash_init(req); + crypto_shash_init(desc); bio_for_each_segment(bvec, bio, iter) { - sg_set_page(&sg, bvec.bv_page, bvec.bv_len, bvec.bv_offset); - ahash_request_set_crypt(req, &sg, NULL, sg.length); - crypto_ahash_update(req); + u8 *src; + + src = kmap_atomic(bvec.bv_page); + crypto_shash_update(desc, src + bvec.bv_offset, bvec.bv_len); + kunmap_atomic(src); + /* REQ_OP_WRITE_SAME has only one segment, * checksum the payload only once. */ if (bio_op(bio) == REQ_OP_WRITE_SAME) break; } - ahash_request_set_crypt(req, NULL, digest, 0); - crypto_ahash_final(req); - ahash_request_zero(req); + crypto_shash_final(desc, digest); + shash_desc_zero(desc); } /* MAYBE merge common code with w_e_end_ov_req */ @@ -367,7 +368,7 @@ static int w_e_send_csum(struct drbd_work *w, int cancel) if (unlikely((peer_req->flags & EE_WAS_ERROR) != 0)) goto out; - digest_size = crypto_ahash_digestsize(peer_device->connection->csums_tfm); + digest_size = crypto_shash_digestsize(peer_device->connection->csums_tfm); digest = kmalloc(digest_size, GFP_NOIO); if (digest) { sector_t sector = peer_req->i.sector; @@ -1205,7 +1206,7 @@ int w_e_end_csum_rs_req(struct drbd_work *w, int cancel) * a real fix would be much more involved, * introducing more locking mechanisms */ if (peer_device->connection->csums_tfm) { - digest_size = crypto_ahash_digestsize(peer_device->connection->csums_tfm); + digest_size = crypto_shash_digestsize(peer_device->connection->csums_tfm); D_ASSERT(device, digest_size == di->digest_size); digest = kmalloc(digest_size, GFP_NOIO); } @@ -1255,7 +1256,7 @@ int w_e_end_ov_req(struct drbd_work *w, int cancel) if (unlikely(cancel)) goto out; - digest_size = crypto_ahash_digestsize(peer_device->connection->verify_tfm); + digest_size = crypto_shash_digestsize(peer_device->connection->verify_tfm); digest = kmalloc(digest_size, GFP_NOIO); if (!digest) { err = 1; /* terminate the connection in case the allocation failed */ @@ -1327,7 +1328,7 @@ int w_e_end_ov_reply(struct drbd_work *w, int cancel) di = peer_req->digest; if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) { - digest_size = crypto_ahash_digestsize(peer_device->connection->verify_tfm); + digest_size = crypto_shash_digestsize(peer_device->connection->verify_tfm); digest = kmalloc(digest_size, GFP_NOIO); if (digest) { drbd_csum_ee(peer_device->connection->verify_tfm, peer_req, digest); -- cgit v1.2.3 From 902d53914f6492b85fcdc35643b28f952dd8d6cf Mon Sep 17 00:00:00 2001 From: jun qian Date: Fri, 7 Sep 2018 10:27:20 -0700 Subject: block: umem: replace spin_lock_bh with spin_lock in tasklet callback As you are already in a tasklet, it is unnecessary to call spin_lock_bh. Signed-off-by: jun qian Signed-off-by: Jens Axboe --- drivers/block/umem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/umem.c b/drivers/block/umem.c index 5c7fb8cc4149..9094ca60949c 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c @@ -421,7 +421,7 @@ static void process_page(unsigned long data) struct cardinfo *card = (struct cardinfo *)data; unsigned int dma_status = card->dma_status; - spin_lock_bh(&card->lock); + spin_lock(&card->lock); if (card->Active < 0) goto out_unlock; page = &card->mm_pages[card->Active]; @@ -496,7 +496,7 @@ static void process_page(unsigned long data) mm_start_io(card); } out_unlock: - spin_unlock_bh(&card->lock); + spin_unlock(&card->lock); while (return_bio) { struct bio *bio = return_bio; -- cgit v1.2.3 From 798ef9e70110d0245797526c930beec7fded7b15 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 11 Sep 2018 14:50:40 -0700 Subject: rsxx: Remove unnecessary parentheses Clang warns when more than one set of parentheses is used for a single conditional statement: drivers/block/rsxx/cregs.c:279:15: warning: equality comparison with extraneous parentheses [-Wparentheses-equality] if ((cmd->op == CREG_OP_READ)) { ~~~~~~~~^~~~~~~~~~~~~~~ drivers/block/rsxx/cregs.c:279:15: note: remove extraneous parentheses around the comparison to silence this warning if ((cmd->op == CREG_OP_READ)) { ~ ^ ~ drivers/block/rsxx/cregs.c:279:15: note: use '=' to turn this equality comparison into an assignment if ((cmd->op == CREG_OP_READ)) { ^~ = 1 warning generated. Reported-by: Nick Desaulniers Reviewed-by: Nick Desaulniers Signed-off-by: Nathan Chancellor Signed-off-by: Jens Axboe --- drivers/block/rsxx/cregs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/block') diff --git a/drivers/block/rsxx/cregs.c b/drivers/block/rsxx/cregs.c index c148e83e4ed7..d9a8758682c9 100644 --- a/drivers/block/rsxx/cregs.c +++ b/drivers/block/rsxx/cregs.c @@ -276,7 +276,7 @@ static void creg_cmd_done(struct work_struct *work) st = -EIO; } - if ((cmd->op == CREG_OP_READ)) { + if (cmd->op == CREG_OP_READ) { unsigned int cnt8 = ioread32(card->regmap + CREG_CNT); /* Paranoid Sanity Checks */ -- cgit v1.2.3 From c839e7a03f92bafd71fd145b470dcdc7f43f2d4c Mon Sep 17 00:00:00 2001 From: "Dennis Zhou (Facebook)" Date: Tue, 11 Sep 2018 14:41:33 -0400 Subject: blkcg: remove bio->bi_css and instead use bio->bi_blkg Prior patches ensured that all bios are now associated with some blkg. This now makes bio->bi_css unnecessary as blkg maintains a reference to the blkcg already. This patch removes the field bi_css and transfers corresponding uses to access via bi_blkg. Signed-off-by: Dennis Zhou Reviewed-by: Josef Bacik Acked-by: Tejun Heo Signed-off-by: Jens Axboe --- drivers/block/loop.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/loop.c b/drivers/block/loop.c index ea9debf59b22..abad6d15f956 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -77,6 +77,7 @@ #include #include #include +#include #include "loop.h" @@ -1760,8 +1761,8 @@ static blk_status_t loop_queue_rq(struct blk_mq_hw_ctx *hctx, /* always use the first bio's css */ #ifdef CONFIG_BLK_CGROUP - if (cmd->use_aio && rq->bio && rq->bio->bi_css) { - cmd->css = rq->bio->bi_css; + if (cmd->use_aio && rq->bio && rq->bio->bi_blkg) { + cmd->css = &bio_blkcg(rq->bio)->css; css_get(cmd->css); } else #endif -- cgit v1.2.3 From fef912bf860e8e7e48a2bfb978a356bba743a8b7 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 28 Sep 2018 08:17:19 +0200 Subject: block: genhd: add 'groups' argument to device_add_disk Update device_add_disk() to take an 'groups' argument so that individual drivers can register a device with additional sysfs attributes. This avoids race condition the driver would otherwise have if these groups were to be created with sysfs_add_groups(). Signed-off-by: Martin Wilck Signed-off-by: Hannes Reinecke Reviewed-by: Christoph Hellwig Reviewed-by: Bart Van Assche Signed-off-by: Jens Axboe --- drivers/block/floppy.c | 2 +- drivers/block/mtip32xx/mtip32xx.c | 2 +- drivers/block/ps3disk.c | 2 +- drivers/block/ps3vram.c | 2 +- drivers/block/rsxx/dev.c | 2 +- drivers/block/skd_main.c | 2 +- drivers/block/sunvdc.c | 2 +- drivers/block/virtio_blk.c | 2 +- drivers/block/xen-blkfront.c | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 48f622728ce6..1bc99e9dfaee 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -4676,7 +4676,7 @@ static int __init do_floppy_init(void) /* to be cleaned up... */ disks[drive]->private_data = (void *)(long)drive; disks[drive]->flags |= GENHD_FL_REMOVABLE; - device_add_disk(&floppy_device[drive].dev, disks[drive]); + device_add_disk(&floppy_device[drive].dev, disks[drive], NULL); } return 0; diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index d0666f5ce003..1d7d48d8a205 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -3861,7 +3861,7 @@ skip_create_disk: set_capacity(dd->disk, capacity); /* Enable the block device and add it to /dev */ - device_add_disk(&dd->pdev->dev, dd->disk); + device_add_disk(&dd->pdev->dev, dd->disk, NULL); dd->bdev = bdget_disk(dd->disk, 0); /* diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c index afe1508d82c6..29a4419e8ba3 100644 --- a/drivers/block/ps3disk.c +++ b/drivers/block/ps3disk.c @@ -500,7 +500,7 @@ static int ps3disk_probe(struct ps3_system_bus_device *_dev) gendisk->disk_name, priv->model, priv->raw_capacity >> 11, get_capacity(gendisk) >> 11); - device_add_disk(&dev->sbd.core, gendisk); + device_add_disk(&dev->sbd.core, gendisk, NULL); return 0; fail_cleanup_queue: diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c index 1e3d5de9d838..c0c50816a10b 100644 --- a/drivers/block/ps3vram.c +++ b/drivers/block/ps3vram.c @@ -769,7 +769,7 @@ static int ps3vram_probe(struct ps3_system_bus_device *dev) dev_info(&dev->core, "%s: Using %lu MiB of GPU memory\n", gendisk->disk_name, get_capacity(gendisk) >> 11); - device_add_disk(&dev->core, gendisk); + device_add_disk(&dev->core, gendisk, NULL); return 0; fail_cleanup_queue: diff --git a/drivers/block/rsxx/dev.c b/drivers/block/rsxx/dev.c index 1a92f9e65937..3894aa0f350b 100644 --- a/drivers/block/rsxx/dev.c +++ b/drivers/block/rsxx/dev.c @@ -226,7 +226,7 @@ int rsxx_attach_dev(struct rsxx_cardinfo *card) set_capacity(card->gendisk, card->size8 >> 9); else set_capacity(card->gendisk, 0); - device_add_disk(CARD_TO_DEV(card), card->gendisk); + device_add_disk(CARD_TO_DEV(card), card->gendisk, NULL); card->bdev_attached = 1; } diff --git a/drivers/block/skd_main.c b/drivers/block/skd_main.c index 87b9e7fbf062..a85c9a622c41 100644 --- a/drivers/block/skd_main.c +++ b/drivers/block/skd_main.c @@ -3104,7 +3104,7 @@ static int skd_bdev_getgeo(struct block_device *bdev, struct hd_geometry *geo) static int skd_bdev_attach(struct device *parent, struct skd_device *skdev) { dev_dbg(&skdev->pdev->dev, "add_disk\n"); - device_add_disk(parent, skdev->disk); + device_add_disk(parent, skdev->disk, NULL); return 0; } diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c index 5ca56bfae63c..09409edce384 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c @@ -850,7 +850,7 @@ static int probe_disk(struct vdc_port *port) port->vdisk_size, (port->vdisk_size >> (20 - 9)), port->vio.ver.major, port->vio.ver.minor); - device_add_disk(&port->vio.vdev->dev, g); + device_add_disk(&port->vio.vdev->dev, g, NULL); return 0; } diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 23752dc99b00..fe80560000a1 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -780,7 +780,7 @@ static int virtblk_probe(struct virtio_device *vdev) virtblk_update_capacity(vblk, false); virtio_device_ready(vdev); - device_add_disk(&vdev->dev, vblk->disk); + device_add_disk(&vdev->dev, vblk->disk, NULL); err = device_create_file(disk_to_dev(vblk->disk), &dev_attr_serial); if (err) goto out_del_disk; diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index a71d817e900d..e5e40272d233 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -2420,7 +2420,7 @@ static void blkfront_connect(struct blkfront_info *info) for (i = 0; i < info->nr_rings; i++) kick_pending_request_queues(&info->rinfo[i]); - device_add_disk(&info->xbdev->dev, info->gd); + device_add_disk(&info->xbdev->dev, info->gd, NULL); info->is_ready = 1; return; -- cgit v1.2.3 From 95cf7809bf9169fec4e4b7bb24b8069d8f354f96 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 28 Sep 2018 08:17:21 +0200 Subject: aoe: register default groups with device_add_disk() Register default sysfs groups during device_add_disk() to avoid a race condition with udev during startup. Signed-off-by: Hannes Reinecke Reviewed-by: Christoph Hellwig Acked-by: Ed L. Cachin Reviewed-by: Bart Van Assche Signed-off-by: Jens Axboe --- drivers/block/aoe/aoe.h | 1 - drivers/block/aoe/aoeblk.c | 21 +++++++-------------- drivers/block/aoe/aoedev.c | 1 - 3 files changed, 7 insertions(+), 16 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h index c0ebda1283cc..015c68017a1c 100644 --- a/drivers/block/aoe/aoe.h +++ b/drivers/block/aoe/aoe.h @@ -201,7 +201,6 @@ int aoeblk_init(void); void aoeblk_exit(void); void aoeblk_gdalloc(void *); void aoedisk_rm_debugfs(struct aoedev *d); -void aoedisk_rm_sysfs(struct aoedev *d); int aoechr_init(void); void aoechr_exit(void); diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index 429ebb84b592..ff770e7d9e52 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c @@ -177,10 +177,15 @@ static struct attribute *aoe_attrs[] = { NULL, }; -static const struct attribute_group attr_group = { +static const struct attribute_group aoe_attr_group = { .attrs = aoe_attrs, }; +static const struct attribute_group *aoe_attr_groups[] = { + &aoe_attr_group, + NULL, +}; + static const struct file_operations aoe_debugfs_fops = { .open = aoe_debugfs_open, .read = seq_read, @@ -219,17 +224,6 @@ aoedisk_rm_debugfs(struct aoedev *d) d->debugfs = NULL; } -static int -aoedisk_add_sysfs(struct aoedev *d) -{ - return sysfs_create_group(&disk_to_dev(d->gd)->kobj, &attr_group); -} -void -aoedisk_rm_sysfs(struct aoedev *d) -{ - sysfs_remove_group(&disk_to_dev(d->gd)->kobj, &attr_group); -} - static int aoeblk_open(struct block_device *bdev, fmode_t mode) { @@ -417,8 +411,7 @@ aoeblk_gdalloc(void *vp) spin_unlock_irqrestore(&d->lock, flags); - add_disk(gd); - aoedisk_add_sysfs(d); + device_add_disk(NULL, gd, aoe_attr_groups); aoedisk_add_debugfs(d); spin_lock_irqsave(&d->lock, flags); diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c index 41060e9cedf2..f29a140cdbc1 100644 --- a/drivers/block/aoe/aoedev.c +++ b/drivers/block/aoe/aoedev.c @@ -275,7 +275,6 @@ freedev(struct aoedev *d) del_timer_sync(&d->timer); if (d->gd) { aoedisk_rm_debugfs(d); - aoedisk_rm_sysfs(d); del_gendisk(d->gd); put_disk(d->gd); blk_cleanup_queue(d->blkq); -- cgit v1.2.3 From 98af4d4df889dcea3bc0ce6b8a04759658ba8826 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 28 Sep 2018 08:17:22 +0200 Subject: zram: register default groups with device_add_disk() Register default sysfs groups during device_add_disk() to avoid a race condition with udev during startup. Signed-off-by: Hannes Reinecke Cc: Minchan Kim Cc: Nitin Gupta Reviewed-by: Christoph Hellwig Reviewed-by: Bart Van Assche Signed-off-by: Jens Axboe --- drivers/block/zram/zram_drv.c | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index a1d6b5597c17..4879595200e1 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -1636,6 +1636,11 @@ static const struct attribute_group zram_disk_attr_group = { .attrs = zram_disk_attrs, }; +static const struct attribute_group *zram_disk_attr_groups[] = { + &zram_disk_attr_group, + NULL, +}; + /* * Allocate and initialize new zram device. the function returns * '>= 0' device_id upon success, and negative value otherwise. @@ -1716,24 +1721,14 @@ static int zram_add(void) zram->disk->queue->backing_dev_info->capabilities |= (BDI_CAP_STABLE_WRITES | BDI_CAP_SYNCHRONOUS_IO); - add_disk(zram->disk); - - ret = sysfs_create_group(&disk_to_dev(zram->disk)->kobj, - &zram_disk_attr_group); - if (ret < 0) { - pr_err("Error creating sysfs group for device %d\n", - device_id); - goto out_free_disk; - } + device_add_disk(NULL, zram->disk, zram_disk_attr_groups); + strlcpy(zram->compressor, default_compressor, sizeof(zram->compressor)); zram_debugfs_register(zram); pr_info("Added device: %s\n", zram->disk->disk_name); return device_id; -out_free_disk: - del_gendisk(zram->disk); - put_disk(zram->disk); out_free_queue: blk_cleanup_queue(queue); out_free_idr: @@ -1762,15 +1757,6 @@ static int zram_remove(struct zram *zram) mutex_unlock(&bdev->bd_mutex); zram_debugfs_unregister(zram); - /* - * Remove sysfs first, so no one will perform a disksize - * store while we destroy the devices. This also helps during - * hot_remove -- zram_reset_device() is the last holder of - * ->init_lock, no later/concurrent disksize_store() or any - * other sysfs handlers are possible. - */ - sysfs_remove_group(&disk_to_dev(zram->disk)->kobj, - &zram_disk_attr_group); /* Make sure all the pending I/O are finished */ fsync_bdev(bdev); -- cgit v1.2.3 From e982c4d0a29b1d61fbe7716a8dcf8984936d6730 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 28 Sep 2018 08:17:23 +0200 Subject: virtio-blk: modernize sysfs attribute creation Use new-style DEVICE_ATTR_RO/DEVICE_ATTR_RW to create the sysfs attributes and register the disk with default sysfs attribute groups. Signed-off-by: Hannes Reinecke Reviewed-by: Christoph Hellwig Acked-by: Michael S. Tsirkin Reviewed-by: Bart Van Assche Signed-off-by: Jens Axboe --- drivers/block/virtio_blk.c | 68 ++++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 29 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index fe80560000a1..086c6bb12baa 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -351,8 +351,8 @@ static int minor_to_index(int minor) return minor >> PART_BITS; } -static ssize_t virtblk_serial_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t serial_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct gendisk *disk = dev_to_disk(dev); int err; @@ -371,7 +371,7 @@ static ssize_t virtblk_serial_show(struct device *dev, return err; } -static DEVICE_ATTR(serial, 0444, virtblk_serial_show, NULL); +static DEVICE_ATTR_RO(serial); /* The queue's logical block size must be set before calling this */ static void virtblk_update_capacity(struct virtio_blk *vblk, bool resize) @@ -545,8 +545,8 @@ static const char *const virtblk_cache_types[] = { }; static ssize_t -virtblk_cache_type_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +cache_type_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct gendisk *disk = dev_to_disk(dev); struct virtio_blk *vblk = disk->private_data; @@ -564,8 +564,7 @@ virtblk_cache_type_store(struct device *dev, struct device_attribute *attr, } static ssize_t -virtblk_cache_type_show(struct device *dev, struct device_attribute *attr, - char *buf) +cache_type_show(struct device *dev, struct device_attribute *attr, char *buf) { struct gendisk *disk = dev_to_disk(dev); struct virtio_blk *vblk = disk->private_data; @@ -575,12 +574,38 @@ virtblk_cache_type_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, 40, "%s\n", virtblk_cache_types[writeback]); } -static const struct device_attribute dev_attr_cache_type_ro = - __ATTR(cache_type, 0444, - virtblk_cache_type_show, NULL); -static const struct device_attribute dev_attr_cache_type_rw = - __ATTR(cache_type, 0644, - virtblk_cache_type_show, virtblk_cache_type_store); +static DEVICE_ATTR_RW(cache_type); + +static struct attribute *virtblk_attrs[] = { + &dev_attr_serial.attr, + &dev_attr_cache_type.attr, + NULL, +}; + +static umode_t virtblk_attrs_are_visible(struct kobject *kobj, + struct attribute *a, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct gendisk *disk = dev_to_disk(dev); + struct virtio_blk *vblk = disk->private_data; + struct virtio_device *vdev = vblk->vdev; + + if (a == &dev_attr_cache_type.attr && + !virtio_has_feature(vdev, VIRTIO_BLK_F_CONFIG_WCE)) + return S_IRUGO; + + return a->mode; +} + +static const struct attribute_group virtblk_attr_group = { + .attrs = virtblk_attrs, + .is_visible = virtblk_attrs_are_visible, +}; + +static const struct attribute_group *virtblk_attr_groups[] = { + &virtblk_attr_group, + NULL, +}; static int virtblk_init_request(struct blk_mq_tag_set *set, struct request *rq, unsigned int hctx_idx, unsigned int numa_node) @@ -780,24 +805,9 @@ static int virtblk_probe(struct virtio_device *vdev) virtblk_update_capacity(vblk, false); virtio_device_ready(vdev); - device_add_disk(&vdev->dev, vblk->disk, NULL); - err = device_create_file(disk_to_dev(vblk->disk), &dev_attr_serial); - if (err) - goto out_del_disk; - - if (virtio_has_feature(vdev, VIRTIO_BLK_F_CONFIG_WCE)) - err = device_create_file(disk_to_dev(vblk->disk), - &dev_attr_cache_type_rw); - else - err = device_create_file(disk_to_dev(vblk->disk), - &dev_attr_cache_type_ro); - if (err) - goto out_del_disk; + device_add_disk(&vdev->dev, vblk->disk, virtblk_attr_groups); return 0; -out_del_disk: - del_gendisk(vblk->disk); - blk_cleanup_queue(vblk->disk->queue); out_free_tags: blk_mq_free_tag_set(&vblk->tag_set); out_put_disk: -- cgit v1.2.3 From fb6360b1ef33b7799e6a81e1075a47e3b8ae01fd Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Tue, 2 Oct 2018 12:24:40 +0200 Subject: pktcdvd: fix fall-through annotation Replace "fallthru" with a proper "fall through" annotation. This fix is part of the ongoing efforts to enabling -Wimplicit-fallthrough Signed-off-by: Gustavo A. R. Silva Signed-off-by: Jens Axboe --- drivers/block/pktcdvd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/block') diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 6f1d25c1eb64..9381f4e3b221 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -2645,7 +2645,7 @@ static int pkt_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, */ if (pd->refcnt == 1) pkt_lock_door(pd, 0); - /* fallthru */ + /* fall through */ /* * forward selected CDROM ioctls to CD-ROM, for UDF */ -- cgit v1.2.3 From 9305455acfa65a2749cd2329d027bf944b26e14c Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 3 Oct 2018 13:56:25 -0700 Subject: block: Finish renaming REQ_DISCARD into REQ_OP_DISCARD Some time ago REQ_DISCARD was renamed into REQ_OP_DISCARD. Some comments and documentation files were not updated however. Update these comments and documentation files. See also commit 4e1b2d52a80d ("block, fs, drivers: remove REQ_OP compat defs and related code"). Signed-off-by: Bart Van Assche Cc: Mike Christie Cc: Martin K. Petersen Cc: Philipp Reisner Cc: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_int.h | 2 +- drivers/block/drbd/drbd_main.c | 2 +- drivers/block/drbd/drbd_protocol.h | 4 ++-- drivers/block/drbd/drbd_req.c | 2 +- drivers/block/drbd/drbd_worker.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 8a4c1328e6f9..1e47db57b9d2 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -429,7 +429,7 @@ enum { __EE_CALL_AL_COMPLETE_IO, __EE_MAY_SET_IN_SYNC, - /* is this a TRIM aka REQ_DISCARD? */ + /* is this a TRIM aka REQ_OP_DISCARD? */ __EE_IS_TRIM, /* In case a barrier failed, diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 15a9ffce9012..55fd104f1ed4 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -1673,7 +1673,7 @@ static u32 bio_flags_to_wire(struct drbd_connection *connection, return bio->bi_opf & REQ_SYNC ? DP_RW_SYNC : 0; } -/* Used to send write or TRIM aka REQ_DISCARD requests +/* Used to send write or TRIM aka REQ_OP_DISCARD requests * R_PRIMARY -> Peer (P_DATA, P_TRIM) */ int drbd_send_dblock(struct drbd_peer_device *peer_device, struct drbd_request *req) diff --git a/drivers/block/drbd/drbd_protocol.h b/drivers/block/drbd/drbd_protocol.h index c3081f93051c..48dabbb21e11 100644 --- a/drivers/block/drbd/drbd_protocol.h +++ b/drivers/block/drbd/drbd_protocol.h @@ -57,7 +57,7 @@ enum drbd_packet { P_PROTOCOL_UPDATE = 0x2d, /* data sock: is used in established connections */ /* 0x2e to 0x30 reserved, used in drbd 9 */ - /* REQ_DISCARD. We used "discard" in different contexts before, + /* REQ_OP_DISCARD. We used "discard" in different contexts before, * which is why I chose TRIM here, to disambiguate. */ P_TRIM = 0x31, @@ -126,7 +126,7 @@ struct p_header100 { #define DP_UNPLUG 8 /* not used anymore */ #define DP_FUA 16 /* equals REQ_FUA */ #define DP_FLUSH 32 /* equals REQ_PREFLUSH */ -#define DP_DISCARD 64 /* equals REQ_DISCARD */ +#define DP_DISCARD 64 /* equals REQ_OP_DISCARD */ #define DP_SEND_RECEIVE_ACK 128 /* This is a proto B write request */ #define DP_SEND_WRITE_ACK 256 /* This is a proto C write request */ #define DP_WSAME 512 /* equiv. REQ_WRITE_SAME */ diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 19cac36e9737..1c4da17e902e 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -650,7 +650,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, case DISCARD_COMPLETED_NOTSUPP: case DISCARD_COMPLETED_WITH_ERROR: /* I'd rather not detach from local disk just because it - * failed a REQ_DISCARD. */ + * failed a REQ_OP_DISCARD. */ mod_rq_state(req, m, RQ_LOCAL_PENDING, RQ_LOCAL_COMPLETED); break; diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index c7ef48efe871..99255d0c9e2f 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -152,7 +152,7 @@ void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __releases(l do_wake = list_empty(block_id == ID_SYNCER ? &device->sync_ee : &device->active_ee); - /* FIXME do we want to detach for failed REQ_DISCARD? + /* FIXME do we want to detach for failed REQ_OP_DISCARD? * ((peer_req->flags & (EE_WAS_ERROR|EE_IS_TRIM)) == EE_WAS_ERROR) */ if (peer_req->flags & EE_WAS_ERROR) __drbd_chk_io_error(device, DRBD_WRITE_ERROR); -- cgit v1.2.3 From 486c6fba90f64d8d6e09f5a36aa722af6b52828c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 9 Oct 2018 16:41:01 +0200 Subject: drivers/block: remove redundant 'default n' from Kconfig-s 'default n' is the default value for any bool or tristate Kconfig setting so there is no need to write it explicitly. Also since commit f467c5640c29 ("kconfig: only write '# CONFIG_FOO is not set' for visible symbols") the Kconfig behavior is the same regardless of 'default n' being present or not: ... One side effect of (and the main motivation for) this change is making the following two definitions behave exactly the same: config FOO bool config FOO bool default n With this change, neither of these will generate a '# CONFIG_FOO is not set' line (assuming FOO isn't selected/implied). That might make it clearer to people that a bare 'default n' is redundant. ... Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- drivers/block/Kconfig | 1 - drivers/block/drbd/Kconfig | 1 - drivers/block/zram/Kconfig | 2 -- 3 files changed, 4 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index d4913516823f..8aec33277fda 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -461,7 +461,6 @@ config BLK_DEV_RBD select LIBCRC32C select CRYPTO_AES select CRYPTO - default n help Say Y here if you want include the Rados block device, which stripes a block device over objects stored in the Ceph distributed object diff --git a/drivers/block/drbd/Kconfig b/drivers/block/drbd/Kconfig index 87aab6910d2d..52d885cdccb5 100644 --- a/drivers/block/drbd/Kconfig +++ b/drivers/block/drbd/Kconfig @@ -11,7 +11,6 @@ config BLK_DEV_DRBD depends on PROC_FS && INET select LRU_CACHE select LIBCRC32C - default n help NOTE: In order to authenticate connections you have to select diff --git a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig index 635235759a0a..fcd055457364 100644 --- a/drivers/block/zram/Kconfig +++ b/drivers/block/zram/Kconfig @@ -3,7 +3,6 @@ config ZRAM tristate "Compressed RAM block device support" depends on BLOCK && SYSFS && ZSMALLOC && CRYPTO select CRYPTO_LZO - default n help Creates virtual block devices called /dev/zramX (X = 0, 1, ...). Pages written to these disks are compressed and stored in memory @@ -18,7 +17,6 @@ config ZRAM config ZRAM_WRITEBACK bool "Write back incompressible page to backing device" depends on ZRAM - default n help With incompressible page, there is no memory saving to keep it in memory. Instead, write it out to backing device. -- cgit v1.2.3 From 3582dd291788e9441c3ba9047e55089edb98da5c Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 12 Oct 2018 10:03:14 -0600 Subject: aoe: convert aoeblk to blk-mq Straight forward conversion - instead of rewriting the internal buffer retrieval logic, just replace the previous elevator peeking with an internal list of requests. Reviewed-by: "Ed L. Cashin" Signed-off-by: Jens Axboe --- drivers/block/aoe/aoe.h | 4 ++++ drivers/block/aoe/aoeblk.c | 49 ++++++++++++++++++++++++++++++++++------------ drivers/block/aoe/aoecmd.c | 19 ++++++++++++------ drivers/block/aoe/aoedev.c | 14 +++++++------ 4 files changed, 61 insertions(+), 25 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h index 015c68017a1c..7ca76ed2e71a 100644 --- a/drivers/block/aoe/aoe.h +++ b/drivers/block/aoe/aoe.h @@ -1,4 +1,6 @@ /* Copyright (c) 2013 Coraid, Inc. See COPYING for GPL terms. */ +#include + #define VERSION "85" #define AOE_MAJOR 152 #define DEVICE_NAME "aoe" @@ -164,6 +166,8 @@ struct aoedev { struct gendisk *gd; struct dentry *debugfs; struct request_queue *blkq; + struct list_head rq_list; + struct blk_mq_tag_set tag_set; struct hd_geometry geo; sector_t ssize; struct timer_list timer; diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index ff770e7d9e52..ed26b7287256 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include #include @@ -268,23 +268,25 @@ aoeblk_release(struct gendisk *disk, fmode_t mode) spin_unlock_irqrestore(&d->lock, flags); } -static void -aoeblk_request(struct request_queue *q) +static blk_status_t aoeblk_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { - struct aoedev *d; - struct request *rq; + struct aoedev *d = hctx->queue->queuedata; + + spin_lock_irq(&d->lock); - d = q->queuedata; if ((d->flags & DEVFL_UP) == 0) { pr_info_ratelimited("aoe: device %ld.%d is not up\n", d->aoemajor, d->aoeminor); - while ((rq = blk_peek_request(q))) { - blk_start_request(rq); - aoe_end_request(d, rq, 1); - } - return; + spin_unlock_irq(&d->lock); + blk_mq_start_request(bd->rq); + return BLK_STS_IOERR; } + + list_add_tail(&bd->rq->queuelist, &d->rq_list); aoecmd_work(d); + spin_unlock_irq(&d->lock); + return BLK_STS_OK; } static int @@ -339,6 +341,10 @@ static const struct block_device_operations aoe_bdops = { .owner = THIS_MODULE, }; +static const struct blk_mq_ops aoeblk_mq_ops = { + .queue_rq = aoeblk_queue_rq, +}; + /* alloc_disk and add_disk can sleep */ void aoeblk_gdalloc(void *vp) @@ -347,9 +353,11 @@ aoeblk_gdalloc(void *vp) struct gendisk *gd; mempool_t *mp; struct request_queue *q; + struct blk_mq_tag_set *set; enum { KB = 1024, MB = KB * KB, READ_AHEAD = 2 * MB, }; ulong flags; int late = 0; + int err; spin_lock_irqsave(&d->lock, flags); if (d->flags & DEVFL_GDALLOC @@ -376,10 +384,25 @@ aoeblk_gdalloc(void *vp) d->aoemajor, d->aoeminor); goto err_disk; } - q = blk_init_queue(aoeblk_request, &d->lock); - if (q == NULL) { + + set = &d->tag_set; + set->ops = &aoeblk_mq_ops; + set->nr_hw_queues = 1; + set->queue_depth = 128; + set->numa_node = NUMA_NO_NODE; + set->flags = BLK_MQ_F_SHOULD_MERGE; + err = blk_mq_alloc_tag_set(set); + if (err) { + pr_err("aoe: cannot allocate tag set for %ld.%d\n", + d->aoemajor, d->aoeminor); + goto err_mempool; + } + + q = blk_mq_init_queue(set); + if (IS_ERR(q)) { pr_err("aoe: cannot allocate block queue for %ld.%d\n", d->aoemajor, d->aoeminor); + blk_mq_free_tag_set(set); goto err_mempool; } diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 136dc507d020..bb2fba651bd2 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include @@ -813,7 +813,7 @@ rexmit_timer(struct timer_list *timer) out: if ((d->flags & DEVFL_KICKME) && d->blkq) { d->flags &= ~DEVFL_KICKME; - d->blkq->request_fn(d->blkq); + blk_mq_run_hw_queues(d->blkq, true); } d->timer.expires = jiffies + TIMERTICK; @@ -857,10 +857,12 @@ nextbuf(struct aoedev *d) return d->ip.buf; rq = d->ip.rq; if (rq == NULL) { - rq = blk_peek_request(q); + rq = list_first_entry_or_null(&d->rq_list, struct request, + queuelist); if (rq == NULL) return NULL; - blk_start_request(rq); + list_del_init(&rq->queuelist); + blk_mq_start_request(rq); d->ip.rq = rq; d->ip.nxbio = rq->bio; rq->special = (void *) rqbiocnt(rq); @@ -1045,6 +1047,7 @@ aoe_end_request(struct aoedev *d, struct request *rq, int fastfail) struct bio *bio; int bok; struct request_queue *q; + blk_status_t err = BLK_STS_OK; q = d->blkq; if (rq == d->ip.rq) @@ -1052,11 +1055,15 @@ aoe_end_request(struct aoedev *d, struct request *rq, int fastfail) do { bio = rq->bio; bok = !fastfail && !bio->bi_status; - } while (__blk_end_request(rq, bok ? BLK_STS_OK : BLK_STS_IOERR, bio->bi_iter.bi_size)); + if (!bok) + err = BLK_STS_IOERR; + } while (blk_update_request(rq, bok ? BLK_STS_OK : BLK_STS_IOERR, bio->bi_iter.bi_size)); + + __blk_mq_end_request(rq, err); /* cf. http://lkml.org/lkml/2006/10/31/28 */ if (!fastfail) - __blk_run_queue(q); + blk_mq_run_hw_queues(q, true); } static void diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c index f29a140cdbc1..9063f8efbd3b 100644 --- a/drivers/block/aoe/aoedev.c +++ b/drivers/block/aoe/aoedev.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include #include @@ -197,7 +197,6 @@ aoedev_downdev(struct aoedev *d) { struct aoetgt *t, **tt, **te; struct list_head *head, *pos, *nx; - struct request *rq; int i; d->flags &= ~DEVFL_UP; @@ -225,10 +224,11 @@ aoedev_downdev(struct aoedev *d) /* fast fail all pending I/O */ if (d->blkq) { - while ((rq = blk_peek_request(d->blkq))) { - blk_start_request(rq); - aoe_end_request(d, rq, 1); - } + /* UP is cleared, freeze+quiesce to insure all are errored */ + blk_mq_freeze_queue(d->blkq); + blk_mq_quiesce_queue(d->blkq); + blk_mq_unquiesce_queue(d->blkq); + blk_mq_unfreeze_queue(d->blkq); } if (d->gd) @@ -277,6 +277,7 @@ freedev(struct aoedev *d) aoedisk_rm_debugfs(d); del_gendisk(d->gd); put_disk(d->gd); + blk_mq_free_tag_set(&d->tag_set); blk_cleanup_queue(d->blkq); } t = d->targets; @@ -463,6 +464,7 @@ aoedev_by_aoeaddr(ulong maj, int min, int do_alloc) d->ntargets = NTARGETS; INIT_WORK(&d->work, aoecmd_sleepwork); spin_lock_init(&d->lock); + INIT_LIST_HEAD(&d->rq_list); skb_queue_head_init(&d->skbpool); timer_setup(&d->timer, dummy_timer, 0); d->timer.expires = jiffies + HZ; -- cgit v1.2.3 From 6d1f9dfde7343c4ebfb8f84dcb333af571bb3b22 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 11 Oct 2018 14:56:14 -0600 Subject: skd: fixup usage of legacy IO API We need to be using the mq variant of request requeue here. Fixes: ca33dd92968b ("skd: Convert to blk-mq") Signed-off-by: Jens Axboe --- drivers/block/skd_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/skd_main.c b/drivers/block/skd_main.c index a85c9a622c41..80a5806ede03 100644 --- a/drivers/block/skd_main.c +++ b/drivers/block/skd_main.c @@ -1416,7 +1416,7 @@ static void skd_resolve_req_exception(struct skd_device *skdev, case SKD_CHECK_STATUS_BUSY_IMMINENT: skd_log_skreq(skdev, skreq, "retry(busy)"); - blk_requeue_request(skdev->queue, req); + blk_mq_requeue_request(req, true); dev_info(&skdev->pdev->dev, "drive BUSY imminent\n"); skdev->state = SKD_DRVR_STATE_BUSY_IMMINENT; skdev->timer_countdown = SKD_TIMER_MINUTES(20); @@ -1426,7 +1426,7 @@ static void skd_resolve_req_exception(struct skd_device *skdev, case SKD_CHECK_STATUS_REQUEUE_REQUEST: if ((unsigned long) ++req->special < SKD_MAX_RETRIES) { skd_log_skreq(skdev, skreq, "retry"); - blk_requeue_request(skdev->queue, req); + blk_mq_requeue_request(req, true); break; } /* fall through */ -- cgit v1.2.3 From e50b1e327aeb4b224364aa6f85c1713ff8b3654b Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 11 Oct 2018 17:58:17 -0600 Subject: null_blk: remove legacy IO path We're planning on removing this code completely, kill the old path. Signed-off-by: Jens Axboe --- drivers/block/null_blk_main.c | 107 +++--------------------------------------- 1 file changed, 6 insertions(+), 101 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/null_blk_main.c b/drivers/block/null_blk_main.c index 093b614d6524..0b302d707095 100644 --- a/drivers/block/null_blk_main.c +++ b/drivers/block/null_blk_main.c @@ -616,10 +616,6 @@ static void end_cmd(struct nullb_cmd *cmd) case NULL_Q_MQ: blk_mq_end_request(cmd->rq, cmd->error); return; - case NULL_Q_RQ: - INIT_LIST_HEAD(&cmd->rq->queuelist); - blk_end_request_all(cmd->rq, cmd->error); - break; case NULL_Q_BIO: cmd->bio->bi_status = cmd->error; bio_endio(cmd->bio); @@ -627,15 +623,6 @@ static void end_cmd(struct nullb_cmd *cmd) } free_cmd(cmd); - - /* Restart queue if needed, as we are freeing a tag */ - if (queue_mode == NULL_Q_RQ && blk_queue_stopped(q)) { - unsigned long flags; - - spin_lock_irqsave(q->queue_lock, flags); - blk_start_queue_async(q); - spin_unlock_irqrestore(q->queue_lock, flags); - } } static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer) @@ -1136,25 +1123,14 @@ static void null_stop_queue(struct nullb *nullb) if (nullb->dev->queue_mode == NULL_Q_MQ) blk_mq_stop_hw_queues(q); - else { - spin_lock_irq(q->queue_lock); - blk_stop_queue(q); - spin_unlock_irq(q->queue_lock); - } } static void null_restart_queue_async(struct nullb *nullb) { struct request_queue *q = nullb->q; - unsigned long flags; if (nullb->dev->queue_mode == NULL_Q_MQ) blk_mq_start_stopped_hw_queues(q, true); - else { - spin_lock_irqsave(q->queue_lock, flags); - blk_start_queue_async(q); - spin_unlock_irqrestore(q->queue_lock, flags); - } } static bool cmd_report_zone(struct nullb *nullb, struct nullb_cmd *cmd) @@ -1197,17 +1173,8 @@ static blk_status_t null_handle_cmd(struct nullb_cmd *cmd) /* race with timer */ if (atomic_long_read(&nullb->cur_bytes) > 0) null_restart_queue_async(nullb); - if (dev->queue_mode == NULL_Q_RQ) { - struct request_queue *q = nullb->q; - - spin_lock_irq(q->queue_lock); - rq->rq_flags |= RQF_DONTPREP; - blk_requeue_request(q, rq); - spin_unlock_irq(q->queue_lock); - return BLK_STS_OK; - } else - /* requeue request */ - return BLK_STS_DEV_RESOURCE; + /* requeue request */ + return BLK_STS_DEV_RESOURCE; } } @@ -1278,9 +1245,6 @@ out: case NULL_Q_MQ: blk_mq_complete_request(cmd->rq); break; - case NULL_Q_RQ: - blk_complete_request(cmd->rq); - break; case NULL_Q_BIO: /* * XXX: no proper submitting cpu information available. @@ -1349,30 +1313,6 @@ static blk_qc_t null_queue_bio(struct request_queue *q, struct bio *bio) return BLK_QC_T_NONE; } -static enum blk_eh_timer_return null_rq_timed_out_fn(struct request *rq) -{ - pr_info("null: rq %p timed out\n", rq); - __blk_complete_request(rq); - return BLK_EH_DONE; -} - -static int null_rq_prep_fn(struct request_queue *q, struct request *req) -{ - struct nullb *nullb = q->queuedata; - struct nullb_queue *nq = nullb_to_queue(nullb); - struct nullb_cmd *cmd; - - cmd = alloc_cmd(nq, 0); - if (cmd) { - cmd->rq = req; - req->special = cmd; - return BLKPREP_OK; - } - blk_stop_queue(q); - - return BLKPREP_DEFER; -} - static bool should_timeout_request(struct request *rq) { #ifdef CONFIG_BLK_DEV_NULL_BLK_FAULT_INJECTION @@ -1391,27 +1331,6 @@ static bool should_requeue_request(struct request *rq) return false; } -static void null_request_fn(struct request_queue *q) -{ - struct request *rq; - - while ((rq = blk_fetch_request(q)) != NULL) { - struct nullb_cmd *cmd = rq->special; - - /* just ignore the request */ - if (should_timeout_request(rq)) - continue; - if (should_requeue_request(rq)) { - blk_requeue_request(q, rq); - continue; - } - - spin_unlock_irq(q->queue_lock); - null_handle_cmd(cmd); - spin_lock_irq(q->queue_lock); - } -} - static enum blk_eh_timer_return null_timeout_rq(struct request *rq, bool res) { pr_info("null: rq %p timed out\n", rq); @@ -1766,24 +1685,6 @@ static int null_add_dev(struct nullb_device *dev) rv = init_driver_queues(nullb); if (rv) goto out_cleanup_blk_queue; - } else { - nullb->q = blk_init_queue_node(null_request_fn, &nullb->lock, - dev->home_node); - if (!nullb->q) { - rv = -ENOMEM; - goto out_cleanup_queues; - } - - if (!null_setup_fault()) - goto out_cleanup_blk_queue; - - blk_queue_prep_rq(nullb->q, null_rq_prep_fn); - blk_queue_softirq_done(nullb->q, null_softirq_done_fn); - blk_queue_rq_timed_out(nullb->q, null_rq_timed_out_fn); - nullb->q->rq_timeout = 5 * HZ; - rv = init_driver_queues(nullb); - if (rv) - goto out_cleanup_blk_queue; } if (dev->mbps) { @@ -1865,6 +1766,10 @@ static int __init null_init(void) return -EINVAL; } + if (g_queue_mode == NULL_Q_RQ) { + pr_err("null_blk: legacy IO path no longer available\n"); + return -EINVAL; + } if (g_queue_mode == NULL_Q_MQ && g_use_per_node_hctx) { if (g_submit_queues != nr_online_nodes) { pr_warn("null_blk: submit_queues param is set to %u.\n", -- cgit v1.2.3 From de038597be8809619c4f17d70e86dab936bb1a10 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Tue, 16 Oct 2018 01:45:26 +0000 Subject: null_blk: remove set but not used variable 'q' Fixes gcc '-Wunused-but-set-variable' warning: drivers/block/null_blk_main.c: In function 'end_cmd': drivers/block/null_blk_main.c:609:24: warning: variable 'q' set but not used [-Wunused-but-set-variable] It not used any more after commit e50b1e327aeb ("null_blk: remove legacy IO path") Signed-off-by: YueHaibing Signed-off-by: Jens Axboe --- drivers/block/null_blk_main.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/null_blk_main.c b/drivers/block/null_blk_main.c index 0b302d707095..e94591021682 100644 --- a/drivers/block/null_blk_main.c +++ b/drivers/block/null_blk_main.c @@ -606,12 +606,8 @@ static struct nullb_cmd *alloc_cmd(struct nullb_queue *nq, int can_wait) static void end_cmd(struct nullb_cmd *cmd) { - struct request_queue *q = NULL; int queue_mode = cmd->nq->dev->queue_mode; - if (cmd->rq) - q = cmd->rq->q; - switch (queue_mode) { case NULL_Q_MQ: blk_mq_end_request(cmd->rq, cmd->error); -- cgit v1.2.3 From fab1adcf9503ccf191aec9ee42580f7dc1eb6237 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 15 Oct 2018 13:32:01 -0600 Subject: ps3disk: convert to blk-mq Convert from the old request_fn style driver to blk-mq. Cc: Benjamin Herrenschmidt Tested-by: Geoff Levand Signed-off-by: Jens Axboe --- drivers/block/ps3disk.c | 86 +++++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 42 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c index 29a4419e8ba3..4e1d9b31f60c 100644 --- a/drivers/block/ps3disk.c +++ b/drivers/block/ps3disk.c @@ -19,7 +19,7 @@ */ #include -#include +#include #include #include @@ -42,6 +42,7 @@ struct ps3disk_private { spinlock_t lock; /* Request queue spinlock */ struct request_queue *queue; + struct blk_mq_tag_set tag_set; struct gendisk *gendisk; unsigned int blocking_factor; struct request *req; @@ -118,8 +119,8 @@ static void ps3disk_scatter_gather(struct ps3_storage_device *dev, } } -static int ps3disk_submit_request_sg(struct ps3_storage_device *dev, - struct request *req) +static blk_status_t ps3disk_submit_request_sg(struct ps3_storage_device *dev, + struct request *req) { struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); int write = rq_data_dir(req), res; @@ -158,16 +159,15 @@ static int ps3disk_submit_request_sg(struct ps3_storage_device *dev, if (res) { dev_err(&dev->sbd.core, "%s:%u: %s failed %d\n", __func__, __LINE__, op, res); - __blk_end_request_all(req, BLK_STS_IOERR); - return 0; + return BLK_STS_IOERR; } priv->req = req; - return 1; + return BLK_STS_OK; } -static int ps3disk_submit_flush_request(struct ps3_storage_device *dev, - struct request *req) +static blk_status_t ps3disk_submit_flush_request(struct ps3_storage_device *dev, + struct request *req) { struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); u64 res; @@ -180,50 +180,45 @@ static int ps3disk_submit_flush_request(struct ps3_storage_device *dev, if (res) { dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%llx\n", __func__, __LINE__, res); - __blk_end_request_all(req, BLK_STS_IOERR); - return 0; + return BLK_STS_IOERR; } priv->req = req; - return 1; + return BLK_STS_OK; } -static void ps3disk_do_request(struct ps3_storage_device *dev, - struct request_queue *q) +static blk_status_t ps3disk_do_request(struct ps3_storage_device *dev, + struct request *req) { - struct request *req; - dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__); - while ((req = blk_fetch_request(q))) { - switch (req_op(req)) { - case REQ_OP_FLUSH: - if (ps3disk_submit_flush_request(dev, req)) - return; - break; - case REQ_OP_READ: - case REQ_OP_WRITE: - if (ps3disk_submit_request_sg(dev, req)) - return; - break; - default: - blk_dump_rq_flags(req, DEVICE_NAME " bad request"); - __blk_end_request_all(req, BLK_STS_IOERR); - } + switch (req_op(req)) { + case REQ_OP_FLUSH: + return ps3disk_submit_flush_request(dev, req); + case REQ_OP_READ: + case REQ_OP_WRITE: + return ps3disk_submit_request_sg(dev, req); + default: + blk_dump_rq_flags(req, DEVICE_NAME " bad request"); + return BLK_STS_IOERR; } } -static void ps3disk_request(struct request_queue *q) +static blk_status_t ps3disk_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { + struct request_queue *q = hctx->queue; struct ps3_storage_device *dev = q->queuedata; struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); + blk_status_t ret; - if (priv->req) { - dev_dbg(&dev->sbd.core, "%s:%u busy\n", __func__, __LINE__); - return; - } + blk_mq_start_request(bd->rq); + + spin_lock_irq(&priv->lock); + ret = ps3disk_do_request(dev, bd->rq); + spin_unlock_irq(&priv->lock); - ps3disk_do_request(dev, q); + return ret; } static irqreturn_t ps3disk_interrupt(int irq, void *data) @@ -280,11 +275,11 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data) } spin_lock(&priv->lock); - __blk_end_request_all(req, error); priv->req = NULL; - ps3disk_do_request(dev, priv->queue); + blk_mq_end_request(req, error); spin_unlock(&priv->lock); + blk_mq_run_hw_queues(priv->queue, true); return IRQ_HANDLED; } @@ -404,6 +399,10 @@ static unsigned long ps3disk_mask; static DEFINE_MUTEX(ps3disk_mask_mutex); +static const struct blk_mq_ops ps3disk_mq_ops = { + .queue_rq = ps3disk_queue_rq, +}; + static int ps3disk_probe(struct ps3_system_bus_device *_dev) { struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); @@ -454,11 +453,12 @@ static int ps3disk_probe(struct ps3_system_bus_device *_dev) ps3disk_identify(dev); - queue = blk_init_queue(ps3disk_request, &priv->lock); - if (!queue) { - dev_err(&dev->sbd.core, "%s:%u: blk_init_queue failed\n", + queue = blk_mq_init_sq_queue(&priv->tag_set, &ps3disk_mq_ops, 1, + BLK_MQ_F_SHOULD_MERGE); + if (IS_ERR(queue)) { + dev_err(&dev->sbd.core, "%s:%u: blk_mq_init_queue failed\n", __func__, __LINE__); - error = -ENOMEM; + error = PTR_ERR(queue); goto fail_teardown; } @@ -505,6 +505,7 @@ static int ps3disk_probe(struct ps3_system_bus_device *_dev) fail_cleanup_queue: blk_cleanup_queue(queue); + blk_mq_free_tag_set(&priv->tag_set); fail_teardown: ps3stor_teardown(dev); fail_free_bounce: @@ -530,6 +531,7 @@ static int ps3disk_remove(struct ps3_system_bus_device *_dev) mutex_unlock(&ps3disk_mask_mutex); del_gendisk(priv->gendisk); blk_cleanup_queue(priv->queue); + blk_mq_free_tag_set(&priv->tag_set); put_disk(priv->gendisk); dev_notice(&dev->sbd.core, "Synchronizing disk cache\n"); ps3disk_sync_cache(dev); -- cgit v1.2.3 From 89c6b16509693332fe13d4bb6b812134de56c16f Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 15 Oct 2018 08:38:52 -0600 Subject: paride: convert pcd to blk-mq Tested-by: Ondrej Zary Signed-off-by: Jens Axboe --- drivers/block/paride/pcd.c | 88 +++++++++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 32 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index a026211afb51..96670eefaeb2 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c @@ -137,7 +137,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY}; #include #include #include -#include +#include #include #include @@ -186,7 +186,8 @@ static int pcd_packet(struct cdrom_device_info *cdi, static int pcd_detect(void); static void pcd_probe_capabilities(void); static void do_pcd_read_drq(void); -static void do_pcd_request(struct request_queue * q); +static blk_status_t pcd_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd); static void do_pcd_read(void); struct pcd_unit { @@ -199,6 +200,8 @@ struct pcd_unit { char *name; /* pcd0, pcd1, etc */ struct cdrom_device_info info; /* uniform cdrom interface */ struct gendisk *disk; + struct blk_mq_tag_set tag_set; + struct list_head rq_list; }; static struct pcd_unit pcd[PCD_UNITS]; @@ -292,6 +295,10 @@ static const struct cdrom_device_ops pcd_dops = { CDC_CD_RW, }; +static const struct blk_mq_ops pcd_mq_ops = { + .queue_rq = pcd_queue_rq, +}; + static void pcd_init_units(void) { struct pcd_unit *cd; @@ -300,13 +307,19 @@ static void pcd_init_units(void) pcd_drive_count = 0; for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { struct gendisk *disk = alloc_disk(1); + if (!disk) continue; - disk->queue = blk_init_queue(do_pcd_request, &pcd_lock); - if (!disk->queue) { - put_disk(disk); + + disk->queue = blk_mq_init_sq_queue(&cd->tag_set, &pcd_mq_ops, + 1, BLK_MQ_F_SHOULD_MERGE); + if (IS_ERR(disk->queue)) { + disk->queue = NULL; continue; } + + INIT_LIST_HEAD(&cd->rq_list); + disk->queue->queuedata = cd; blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH); cd->disk = disk; cd->pi = &cd->pia; @@ -748,18 +761,18 @@ static int pcd_queue; static int set_next_request(void) { struct pcd_unit *cd; - struct request_queue *q; int old_pos = pcd_queue; do { cd = &pcd[pcd_queue]; - q = cd->present ? cd->disk->queue : NULL; if (++pcd_queue == PCD_UNITS) pcd_queue = 0; - if (q) { - pcd_req = blk_fetch_request(q); - if (pcd_req) - break; + if (cd->present && !list_empty(&cd->rq_list)) { + pcd_req = list_first_entry(&cd->rq_list, struct request, + queuelist); + list_del_init(&pcd_req->queuelist); + blk_mq_start_request(pcd_req); + break; } } while (pcd_queue != old_pos); @@ -768,33 +781,41 @@ static int set_next_request(void) static void pcd_request(void) { + struct pcd_unit *cd; + if (pcd_busy) return; - while (1) { - if (!pcd_req && !set_next_request()) - return; - if (rq_data_dir(pcd_req) == READ) { - struct pcd_unit *cd = pcd_req->rq_disk->private_data; - if (cd != pcd_current) - pcd_bufblk = -1; - pcd_current = cd; - pcd_sector = blk_rq_pos(pcd_req); - pcd_count = blk_rq_cur_sectors(pcd_req); - pcd_buf = bio_data(pcd_req->bio); - pcd_busy = 1; - ps_set_intr(do_pcd_read, NULL, 0, nice); - return; - } else { - __blk_end_request_all(pcd_req, BLK_STS_IOERR); - pcd_req = NULL; - } - } + if (!pcd_req && !set_next_request()) + return; + + cd = pcd_req->rq_disk->private_data; + if (cd != pcd_current) + pcd_bufblk = -1; + pcd_current = cd; + pcd_sector = blk_rq_pos(pcd_req); + pcd_count = blk_rq_cur_sectors(pcd_req); + pcd_buf = bio_data(pcd_req->bio); + pcd_busy = 1; + ps_set_intr(do_pcd_read, NULL, 0, nice); } -static void do_pcd_request(struct request_queue *q) +static blk_status_t pcd_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { + struct pcd_unit *cd = hctx->queue->queuedata; + + if (rq_data_dir(bd->rq) != READ) { + blk_mq_start_request(bd->rq); + return BLK_STS_IOERR; + } + + spin_lock_irq(&pcd_lock); + list_add_tail(&bd->rq->queuelist, &cd->rq_list); pcd_request(); + spin_unlock_irq(&pcd_lock); + + return BLK_STS_OK; } static inline void next_request(blk_status_t err) @@ -802,8 +823,10 @@ static inline void next_request(blk_status_t err) unsigned long saved_flags; spin_lock_irqsave(&pcd_lock, saved_flags); - if (!__blk_end_request_cur(pcd_req, err)) + if (!blk_update_request(pcd_req, err, blk_rq_cur_bytes(pcd_req))) { + __blk_mq_end_request(pcd_req, err); pcd_req = NULL; + } pcd_busy = 0; pcd_request(); spin_unlock_irqrestore(&pcd_lock, saved_flags); @@ -1011,6 +1034,7 @@ static void __exit pcd_exit(void) unregister_cdrom(&cd->info); } blk_cleanup_queue(cd->disk->queue); + blk_mq_free_tag_set(&cd->tag_set); put_disk(cd->disk); } unregister_blkdev(major, name); -- cgit v1.2.3 From 99fe8b02a82597a8fa8add6455d0a3037ca16e06 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 15 Oct 2018 13:53:50 -0600 Subject: paride: convert pd to blk-mq Tested-by: Ondrej Zary Signed-off-by: Jens Axboe --- drivers/block/paride/pd.c | 94 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 28 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index 7cf947586fe4..ae4971e5d9a8 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c @@ -151,7 +151,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO, D_SBY, D_DLY, D_SLV}; #include #include #include /* for the eject ioctl */ -#include +#include #include #include #include @@ -236,6 +236,8 @@ struct pd_unit { int alt_geom; char name[PD_NAMELEN]; /* pda, pdb, etc ... */ struct gendisk *gd; + struct blk_mq_tag_set tag_set; + struct list_head rq_list; }; static struct pd_unit pd[PD_UNITS]; @@ -399,9 +401,17 @@ static int set_next_request(void) if (++pd_queue == PD_UNITS) pd_queue = 0; if (q) { - pd_req = blk_fetch_request(q); - if (pd_req) - break; + struct pd_unit *disk = q->queuedata; + + if (list_empty(&disk->rq_list)) + continue; + + pd_req = list_first_entry(&disk->rq_list, + struct request, + queuelist); + list_del_init(&pd_req->queuelist); + blk_mq_start_request(pd_req); + break; } } while (pd_queue != old_pos); @@ -412,7 +422,6 @@ static void run_fsm(void) { while (1) { enum action res; - unsigned long saved_flags; int stop = 0; if (!phase) { @@ -433,19 +442,24 @@ static void run_fsm(void) } switch(res = phase()) { - case Ok: case Fail: + case Ok: case Fail: { + blk_status_t err; + + err = res == Ok ? 0 : BLK_STS_IOERR; pi_disconnect(pi_current); pd_claimed = 0; phase = NULL; - spin_lock_irqsave(&pd_lock, saved_flags); - if (!__blk_end_request_cur(pd_req, - res == Ok ? 0 : BLK_STS_IOERR)) { - if (!set_next_request()) - stop = 1; + spin_lock_irq(&pd_lock); + if (!blk_update_request(pd_req, err, + blk_rq_cur_bytes(pd_req))) { + __blk_mq_end_request(pd_req, err); + pd_req = NULL; + stop = !set_next_request(); } - spin_unlock_irqrestore(&pd_lock, saved_flags); + spin_unlock_irq(&pd_lock); if (stop) return; + } /* fall through */ case Hold: schedule_fsm(); @@ -505,11 +519,17 @@ static int pd_next_buf(void) if (pd_count) return 0; spin_lock_irqsave(&pd_lock, saved_flags); - __blk_end_request_cur(pd_req, 0); - pd_count = blk_rq_cur_sectors(pd_req); - pd_buf = bio_data(pd_req->bio); + if (!blk_update_request(pd_req, 0, blk_rq_cur_bytes(pd_req))) { + __blk_mq_end_request(pd_req, 0); + pd_req = NULL; + pd_count = 0; + pd_buf = NULL; + } else { + pd_count = blk_rq_cur_sectors(pd_req); + pd_buf = bio_data(pd_req->bio); + } spin_unlock_irqrestore(&pd_lock, saved_flags); - return 0; + return !pd_count; } static unsigned long pd_timeout; @@ -726,15 +746,21 @@ static enum action pd_identify(struct pd_unit *disk) /* end of io request engine */ -static void do_pd_request(struct request_queue * q) +static blk_status_t pd_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { - if (pd_req) - return; - pd_req = blk_fetch_request(q); - if (!pd_req) - return; + struct pd_unit *disk = hctx->queue->queuedata; + + spin_lock_irq(&pd_lock); + if (!pd_req) { + pd_req = bd->rq; + blk_mq_start_request(pd_req); + } else + list_add_tail(&bd->rq->queuelist, &disk->rq_list); + spin_unlock_irq(&pd_lock); - schedule_fsm(); + run_fsm(); + return BLK_STS_OK; } static int pd_special_command(struct pd_unit *disk, @@ -847,23 +873,33 @@ static const struct block_device_operations pd_fops = { /* probing */ +static const struct blk_mq_ops pd_mq_ops = { + .queue_rq = pd_queue_rq, +}; + static void pd_probe_drive(struct pd_unit *disk) { - struct gendisk *p = alloc_disk(1 << PD_BITS); + struct gendisk *p; + + p = alloc_disk(1 << PD_BITS); if (!p) return; + strcpy(p->disk_name, disk->name); p->fops = &pd_fops; p->major = major; p->first_minor = (disk - pd) << PD_BITS; disk->gd = p; p->private_data = disk; - p->queue = blk_init_queue(do_pd_request, &pd_lock); - if (!p->queue) { - disk->gd = NULL; - put_disk(p); + + p->queue = blk_mq_init_sq_queue(&disk->tag_set, &pd_mq_ops, 2, + BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_BLOCKING); + if (IS_ERR(p->queue)) { + p->queue = NULL; return; } + + p->queue->queuedata = disk; blk_queue_max_hw_sectors(p->queue, cluster); blk_queue_bounce_limit(p->queue, BLK_BOUNCE_HIGH); @@ -895,6 +931,7 @@ static int pd_detect(void) disk->standby = parm[D_SBY]; if (parm[D_PRT]) pd_drive_count++; + INIT_LIST_HEAD(&disk->rq_list); } par_drv = pi_register_driver(name); @@ -972,6 +1009,7 @@ static void __exit pd_exit(void) disk->gd = NULL; del_gendisk(p); blk_cleanup_queue(p->queue); + blk_mq_free_tag_set(&disk->tag_set); put_disk(p); pi_release(disk->pi); } -- cgit v1.2.3 From 77218ddf46d8d71161776a37739cd1723706ec95 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 15 Oct 2018 08:38:08 -0600 Subject: paride: convert pf to blk-mq Tested-by: Ondrej Zary Signed-off-by: Jens Axboe --- drivers/block/paride/pf.c | 56 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 14 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c index eef7a91f667d..e92e7a8eeeb2 100644 --- a/drivers/block/paride/pf.c +++ b/drivers/block/paride/pf.c @@ -152,7 +152,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_LUN, D_DLY}; #include #include #include -#include +#include #include #include #include @@ -206,7 +206,8 @@ module_param_array(drive3, int, NULL, 0); #define ATAPI_WRITE_10 0x2a static int pf_open(struct block_device *bdev, fmode_t mode); -static void do_pf_request(struct request_queue * q); +static blk_status_t pf_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd); static int pf_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg); static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo); @@ -238,6 +239,8 @@ struct pf_unit { int present; /* device present ? */ char name[PF_NAMELEN]; /* pf0, pf1, ... */ struct gendisk *disk; + struct blk_mq_tag_set tag_set; + struct list_head rq_list; }; static struct pf_unit units[PF_UNITS]; @@ -277,6 +280,10 @@ static const struct block_device_operations pf_fops = { .check_events = pf_check_events, }; +static const struct blk_mq_ops pf_mq_ops = { + .queue_rq = pf_queue_rq, +}; + static void __init pf_init_units(void) { struct pf_unit *pf; @@ -284,14 +291,22 @@ static void __init pf_init_units(void) pf_drive_count = 0; for (unit = 0, pf = units; unit < PF_UNITS; unit++, pf++) { - struct gendisk *disk = alloc_disk(1); + struct gendisk *disk; + + disk = alloc_disk(1); if (!disk) continue; - disk->queue = blk_init_queue(do_pf_request, &pf_spin_lock); - if (!disk->queue) { + + disk->queue = blk_mq_init_sq_queue(&pf->tag_set, &pf_mq_ops, + 1, BLK_MQ_F_SHOULD_MERGE); + if (IS_ERR(disk->queue)) { put_disk(disk); - return; + disk->queue = NULL; + continue; } + + INIT_LIST_HEAD(&pf->rq_list); + disk->queue->queuedata = pf; blk_queue_max_segments(disk->queue, cluster); blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH); pf->disk = disk; @@ -784,18 +799,18 @@ static int pf_queue; static int set_next_request(void) { struct pf_unit *pf; - struct request_queue *q; int old_pos = pf_queue; do { pf = &units[pf_queue]; - q = pf->present ? pf->disk->queue : NULL; if (++pf_queue == PF_UNITS) pf_queue = 0; - if (q) { - pf_req = blk_fetch_request(q); - if (pf_req) - break; + if (pf->present && !list_empty(&pf->rq_list)) { + pf_req = list_first_entry(&pf->rq_list, struct request, + queuelist); + list_del_init(&pf_req->queuelist); + blk_mq_start_request(pf_req); + break; } } while (pf_queue != old_pos); @@ -804,8 +819,12 @@ static int set_next_request(void) static void pf_end_request(blk_status_t err) { - if (pf_req && !__blk_end_request_cur(pf_req, err)) + if (!pf_req) + return; + if (!blk_update_request(pf_req, err, blk_rq_cur_bytes(pf_req))) { + __blk_mq_end_request(pf_req, err); pf_req = NULL; + } } static void pf_request(void) @@ -842,9 +861,17 @@ repeat: } } -static void do_pf_request(struct request_queue *q) +static blk_status_t pf_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { + struct pf_unit *pf = hctx->queue->queuedata; + + spin_lock_irq(&pf_spin_lock); + list_add_tail(&bd->rq->queuelist, &pf->rq_list); pf_request(); + spin_unlock_irq(&pf_spin_lock); + + return BLK_STS_OK; } static int pf_next_buf(void) @@ -1024,6 +1051,7 @@ static void __exit pf_exit(void) continue; del_gendisk(pf->disk); blk_cleanup_queue(pf->disk->queue); + blk_mq_free_tag_set(&pf->tag_set); put_disk(pf->disk); pi_release(pf->pi); } -- cgit v1.2.3 From 804186fa95c871aba621da280284d3bc46746d50 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 15 Oct 2018 09:05:59 -0600 Subject: xsysace: convert to blk-mq Straight forward conversion, using an internal list to enable the driver to pull requests at will. Acked-by: Michal Simek Signed-off-by: Jens Axboe --- drivers/block/xsysace.c | 80 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 25 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index c24589414c75..87ccef4bd69e 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -88,7 +88,7 @@ #include #include #include -#include +#include #include #include #include @@ -209,6 +209,8 @@ struct ace_device { struct device *dev; struct request_queue *queue; struct gendisk *gd; + struct blk_mq_tag_set tag_set; + struct list_head rq_list; /* Inserted CF card parameters */ u16 cf_id[ATA_ID_WORDS]; @@ -462,18 +464,26 @@ static inline void ace_fsm_yieldirq(struct ace_device *ace) ace->fsm_continue_flag = 0; } +static bool ace_has_next_request(struct request_queue *q) +{ + struct ace_device *ace = q->queuedata; + + return !list_empty(&ace->rq_list); +} + /* Get the next read/write request; ending requests that we don't handle */ static struct request *ace_get_next_request(struct request_queue *q) { - struct request *req; + struct ace_device *ace = q->queuedata; + struct request *rq; - while ((req = blk_peek_request(q)) != NULL) { - if (!blk_rq_is_passthrough(req)) - break; - blk_start_request(req); - __blk_end_request_all(req, BLK_STS_IOERR); + rq = list_first_entry_or_null(&ace->rq_list, struct request, queuelist); + if (rq) { + list_del_init(&rq->queuelist); + blk_mq_start_request(rq); } - return req; + + return NULL; } static void ace_fsm_dostate(struct ace_device *ace) @@ -499,11 +509,11 @@ static void ace_fsm_dostate(struct ace_device *ace) /* Drop all in-flight and pending requests */ if (ace->req) { - __blk_end_request_all(ace->req, BLK_STS_IOERR); + blk_mq_end_request(ace->req, BLK_STS_IOERR); ace->req = NULL; } - while ((req = blk_fetch_request(ace->queue)) != NULL) - __blk_end_request_all(req, BLK_STS_IOERR); + while ((req = ace_get_next_request(ace->queue)) != NULL) + blk_mq_end_request(req, BLK_STS_IOERR); /* Drop back to IDLE state and notify waiters */ ace->fsm_state = ACE_FSM_STATE_IDLE; @@ -517,7 +527,7 @@ static void ace_fsm_dostate(struct ace_device *ace) switch (ace->fsm_state) { case ACE_FSM_STATE_IDLE: /* See if there is anything to do */ - if (ace->id_req_count || ace_get_next_request(ace->queue)) { + if (ace->id_req_count || ace_has_next_request(ace->queue)) { ace->fsm_iter_num++; ace->fsm_state = ACE_FSM_STATE_REQ_LOCK; mod_timer(&ace->stall_timer, jiffies + HZ); @@ -651,7 +661,6 @@ static void ace_fsm_dostate(struct ace_device *ace) ace->fsm_state = ACE_FSM_STATE_IDLE; break; } - blk_start_request(req); /* Okay, it's a data request, set it up for transfer */ dev_dbg(ace->dev, @@ -728,7 +737,8 @@ static void ace_fsm_dostate(struct ace_device *ace) } /* bio finished; is there another one? */ - if (__blk_end_request_cur(ace->req, BLK_STS_OK)) { + if (blk_update_request(ace->req, BLK_STS_OK, + blk_rq_cur_bytes(ace->req))) { /* dev_dbg(ace->dev, "next block; h=%u c=%u\n", * blk_rq_sectors(ace->req), * blk_rq_cur_sectors(ace->req)); @@ -854,17 +864,23 @@ static irqreturn_t ace_interrupt(int irq, void *dev_id) /* --------------------------------------------------------------------- * Block ops */ -static void ace_request(struct request_queue * q) +static blk_status_t ace_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { - struct request *req; - struct ace_device *ace; - - req = ace_get_next_request(q); + struct ace_device *ace = hctx->queue->queuedata; + struct request *req = bd->rq; - if (req) { - ace = req->rq_disk->private_data; - tasklet_schedule(&ace->fsm_tasklet); + if (blk_rq_is_passthrough(req)) { + blk_mq_start_request(req); + return BLK_STS_IOERR; } + + spin_lock_irq(&ace->lock); + list_add_tail(&req->queuelist, &ace->rq_list); + spin_unlock_irq(&ace->lock); + + tasklet_schedule(&ace->fsm_tasklet); + return BLK_STS_OK; } static unsigned int ace_check_events(struct gendisk *gd, unsigned int clearing) @@ -957,6 +973,10 @@ static const struct block_device_operations ace_fops = { .getgeo = ace_getgeo, }; +static const struct blk_mq_ops ace_mq_ops = { + .queue_rq = ace_queue_rq, +}; + /* -------------------------------------------------------------------- * SystemACE device setup/teardown code */ @@ -972,6 +992,7 @@ static int ace_setup(struct ace_device *ace) spin_lock_init(&ace->lock); init_completion(&ace->id_completion); + INIT_LIST_HEAD(&ace->rq_list); /* * Map the device @@ -989,9 +1010,15 @@ static int ace_setup(struct ace_device *ace) /* * Initialize the request queue */ - ace->queue = blk_init_queue(ace_request, &ace->lock); - if (ace->queue == NULL) + ace->queue = blk_mq_init_sq_queue(&ace->tag_set, &ace_mq_ops, 2, + BLK_MQ_F_SHOULD_MERGE); + if (IS_ERR(ace->queue)) { + rc = PTR_ERR(ace->queue); + ace->queue = NULL; goto err_blk_initq; + } + ace->queue->queuedata = ace; + blk_queue_logical_block_size(ace->queue, 512); blk_queue_bounce_limit(ace->queue, BLK_BOUNCE_HIGH); @@ -1066,6 +1093,7 @@ err_read: put_disk(ace->gd); err_alloc_disk: blk_cleanup_queue(ace->queue); + blk_mq_free_tag_set(&ace->tag_set); err_blk_initq: iounmap(ace->baseaddr); err_ioremap: @@ -1081,8 +1109,10 @@ static void ace_teardown(struct ace_device *ace) put_disk(ace->gd); } - if (ace->queue) + if (ace->queue) { blk_cleanup_queue(ace->queue); + blk_mq_free_tag_set(&ace->tag_set); + } tasklet_kill(&ace->fsm_tasklet); -- cgit v1.2.3 From 1448a2a5360ae06f25e2edc61ae070dff5c0beb4 Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Thu, 11 Oct 2018 12:20:41 -0700 Subject: swim: fix cleanup on setup error If we fail to allocate the request queue for a disk, we still need to free that disk, not just the previous ones. Additionally, we need to cleanup the previous request queues. Signed-off-by: Omar Sandoval Signed-off-by: Jens Axboe --- drivers/block/swim.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/swim.c b/drivers/block/swim.c index 0e31884a9519..cbe909c51847 100644 --- a/drivers/block/swim.c +++ b/drivers/block/swim.c @@ -887,8 +887,17 @@ static int swim_floppy_init(struct swim_priv *swd) exit_put_disks: unregister_blkdev(FLOPPY_MAJOR, "fd"); - while (drive--) - put_disk(swd->unit[drive].disk); + do { + struct gendisk *disk = swd->unit[drive].disk; + + if (disk) { + if (disk->queue) { + blk_cleanup_queue(disk->queue); + disk->queue = NULL; + } + put_disk(disk); + } + } while (drive--); return err; } -- cgit v1.2.3 From e3896d77b7025c39150eb5ada33ec2c88f4ad445 Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Mon, 15 Oct 2018 09:12:12 -0600 Subject: swim: convert to blk-mq The only interesting thing here is that there may be two floppies (i.e., request queues) sharing the same controller, so we use the global struct swim_priv->lock to check whether the controller is busy. Compile-tested only. Tested-by: Finn Thain Acked-by: Laurent Vivier Signed-off-by: Omar Sandoval Converted to blk_mq_init_sq_queue() Signed-off-by: Jens Axboe --- drivers/block/swim.c | 93 +++++++++++++++++++++++----------------------------- 1 file changed, 41 insertions(+), 52 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/swim.c b/drivers/block/swim.c index cbe909c51847..3fa6fcc34790 100644 --- a/drivers/block/swim.c +++ b/drivers/block/swim.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include @@ -190,6 +190,7 @@ struct floppy_state { int ref_count; struct gendisk *disk; + struct blk_mq_tag_set tag_set; /* parent controller */ @@ -211,7 +212,6 @@ enum head { struct swim_priv { struct swim __iomem *base; spinlock_t lock; - int fdc_queue; int floppy_count; struct floppy_state unit[FD_MAX_UNIT]; }; @@ -525,58 +525,36 @@ static blk_status_t floppy_read_sectors(struct floppy_state *fs, return 0; } -static struct request *swim_next_request(struct swim_priv *swd) +static blk_status_t swim_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { - struct request_queue *q; - struct request *rq; - int old_pos = swd->fdc_queue; + struct floppy_state *fs = hctx->queue->queuedata; + struct swim_priv *swd = fs->swd; + struct request *req = bd->rq; + blk_status_t err; - do { - q = swd->unit[swd->fdc_queue].disk->queue; - if (++swd->fdc_queue == swd->floppy_count) - swd->fdc_queue = 0; - if (q) { - rq = blk_fetch_request(q); - if (rq) - return rq; - } - } while (swd->fdc_queue != old_pos); + if (!spin_trylock_irq(&swd->lock)) + return BLK_STS_DEV_RESOURCE; - return NULL; -} + blk_mq_start_request(req); -static void do_fd_request(struct request_queue *q) -{ - struct swim_priv *swd = q->queuedata; - struct request *req; - struct floppy_state *fs; + if (!fs->disk_in || rq_data_dir(req) == WRITE) { + err = BLK_STS_IOERR; + goto out; + } - req = swim_next_request(swd); - while (req) { - blk_status_t err = BLK_STS_IOERR; + do { + err = floppy_read_sectors(fs, blk_rq_pos(req), + blk_rq_cur_sectors(req), + bio_data(req->bio)); + } while (blk_update_request(req, err, blk_rq_cur_bytes(req))); + __blk_mq_end_request(req, err); - fs = req->rq_disk->private_data; - if (blk_rq_pos(req) >= fs->total_secs) - goto done; - if (!fs->disk_in) - goto done; - if (rq_data_dir(req) == WRITE && fs->write_protected) - goto done; + err = BLK_STS_OK; +out: + spin_unlock_irq(&swd->lock); + return err; - switch (rq_data_dir(req)) { - case WRITE: - /* NOT IMPLEMENTED */ - break; - case READ: - err = floppy_read_sectors(fs, blk_rq_pos(req), - blk_rq_cur_sectors(req), - bio_data(req->bio)); - break; - } - done: - if (!__blk_end_request_cur(req, err)) - req = swim_next_request(swd); - } } static struct floppy_struct floppy_type[4] = { @@ -823,6 +801,10 @@ static int swim_add_floppy(struct swim_priv *swd, enum drive_location location) return 0; } +static const struct blk_mq_ops swim_mq_ops = { + .queue_rq = swim_queue_rq, +}; + static int swim_floppy_init(struct swim_priv *swd) { int err; @@ -852,20 +834,25 @@ static int swim_floppy_init(struct swim_priv *swd) spin_lock_init(&swd->lock); for (drive = 0; drive < swd->floppy_count; drive++) { + struct request_queue *q; + swd->unit[drive].disk = alloc_disk(1); if (swd->unit[drive].disk == NULL) { err = -ENOMEM; goto exit_put_disks; } - swd->unit[drive].disk->queue = blk_init_queue(do_fd_request, - &swd->lock); - if (!swd->unit[drive].disk->queue) { - err = -ENOMEM; + + q = blk_mq_init_sq_queue(&swd->unit[drive].tag_set, &swim_mq_ops, + 2, BLK_MQ_F_SHOULD_MERGE); + if (IS_ERR(q)) { + err = PTR_ERR(q); goto exit_put_disks; } + + swd->unit[drive].disk->queue = q; blk_queue_bounce_limit(swd->unit[drive].disk->queue, BLK_BOUNCE_HIGH); - swd->unit[drive].disk->queue->queuedata = swd; + swd->unit[drive].disk->queue->queuedata = &swd->unit[drive]; swd->unit[drive].swd = swd; } @@ -895,6 +882,7 @@ exit_put_disks: blk_cleanup_queue(disk->queue); disk->queue = NULL; } + blk_mq_free_tag_set(&swd->unit[drive].tag_set); put_disk(disk); } } while (drive--); @@ -970,6 +958,7 @@ static int swim_remove(struct platform_device *dev) for (drive = 0; drive < swd->floppy_count; drive++) { del_gendisk(swd->unit[drive].disk); blk_cleanup_queue(swd->unit[drive].disk->queue); + blk_mq_free_tag_set(&swd->unit[drive].tag_set); put_disk(swd->unit[drive].disk); } -- cgit v1.2.3 From dbaa54b65e7a06e6ff2192f8fe92ecd51accc766 Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Thu, 11 Oct 2018 12:20:43 -0700 Subject: swim3: add real error handling in setup The driver doesn't have support for removing a device that has already been configured, but with more careful ordering we can avoid the need for that and make sure that we don't leak generic resources. Signed-off-by: Omar Sandoval Signed-off-by: Jens Axboe --- drivers/block/swim3.c | 60 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 24 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index 469541c1e51e..df7ebe016e2c 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c @@ -1202,47 +1202,59 @@ static int swim3_add_device(struct macio_dev *mdev, int index) static int swim3_attach(struct macio_dev *mdev, const struct of_device_id *match) { + struct floppy_state *fs; struct gendisk *disk; - int index, rc; + int rc; - index = floppy_count++; - if (index >= MAX_FLOPPIES) + if (floppy_count >= MAX_FLOPPIES) return -ENXIO; - /* Add the drive */ - rc = swim3_add_device(mdev, index); - if (rc) - return rc; - /* Now register that disk. Same comment about failure handling */ - disk = disks[index] = alloc_disk(1); - if (disk == NULL) - return -ENOMEM; + if (floppy_count == 0) { + rc = register_blkdev(FLOPPY_MAJOR, "fd"); + if (rc) + return rc; + } + + fs = &floppy_states[floppy_count]; + + disk = alloc_disk(1); + if (disk == NULL) { + rc = -ENOMEM; + goto out_unregister; + } disk->queue = blk_init_queue(do_fd_request, &swim3_lock); if (disk->queue == NULL) { - put_disk(disk); - return -ENOMEM; + rc = -ENOMEM; + goto out_put_disk; } blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH); - disk->queue->queuedata = &floppy_states[index]; + disk->queue->queuedata = fs; - if (index == 0) { - /* If we failed, there isn't much we can do as the driver is still - * too dumb to remove the device, just bail out - */ - if (register_blkdev(FLOPPY_MAJOR, "fd")) - return 0; - } + rc = swim3_add_device(mdev, floppy_count); + if (rc) + goto out_cleanup_queue; disk->major = FLOPPY_MAJOR; - disk->first_minor = index; + disk->first_minor = floppy_count; disk->fops = &floppy_fops; - disk->private_data = &floppy_states[index]; + disk->private_data = fs; disk->flags |= GENHD_FL_REMOVABLE; - sprintf(disk->disk_name, "fd%d", index); + sprintf(disk->disk_name, "fd%d", floppy_count); set_capacity(disk, 2880); add_disk(disk); + disks[floppy_count++] = disk; return 0; + +out_cleanup_queue: + blk_cleanup_queue(disk->queue); + disk->queue = NULL; +out_put_disk: + put_disk(disk); +out_unregister: + if (floppy_count == 0) + unregister_blkdev(FLOPPY_MAJOR, "fd"); + return rc; } static const struct of_device_id swim3_match[] = -- cgit v1.2.3 From 8ccb8cb1892b27655247ff42867665763793ffe8 Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Mon, 15 Oct 2018 09:14:46 -0600 Subject: swim3: convert to blk-mq Pretty simple conversion. grab_drive() could probably be replaced by some freeze/quiesce incantation, but I left it alone, and just used freeze/quiesce for eject. Compile-tested only. Cc: Benjamin Herrenschmidt Signed-off-by: Omar Sandoval Converted to blk_mq_init_sq_queue(). Signed-off-by: Jens Axboe --- drivers/block/swim3.c | 153 +++++++++++++++++++++----------------------------- 1 file changed, 65 insertions(+), 88 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index df7ebe016e2c..c1c676a33e4a 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include @@ -206,6 +206,7 @@ struct floppy_state { char dbdma_cmd_space[5 * sizeof(struct dbdma_cmd)]; int index; struct request *cur_req; + struct blk_mq_tag_set tag_set; }; #define swim3_err(fmt, arg...) dev_err(&fs->mdev->ofdev.dev, "[fd%d] " fmt, fs->index, arg) @@ -260,16 +261,15 @@ static int floppy_revalidate(struct gendisk *disk); static bool swim3_end_request(struct floppy_state *fs, blk_status_t err, unsigned int nr_bytes) { struct request *req = fs->cur_req; - int rc; swim3_dbg(" end request, err=%d nr_bytes=%d, cur_req=%p\n", err, nr_bytes, req); if (err) nr_bytes = blk_rq_cur_bytes(req); - rc = __blk_end_request(req, err, nr_bytes); - if (rc) + if (blk_update_request(req, err, nr_bytes)) return true; + __blk_mq_end_request(req, err); fs->cur_req = NULL; return false; } @@ -309,86 +309,58 @@ static int swim3_readbit(struct floppy_state *fs, int bit) return (stat & DATA) == 0; } -static void start_request(struct floppy_state *fs) +static blk_status_t swim3_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { - struct request *req; + struct floppy_state *fs = hctx->queue->queuedata; + struct request *req = bd->rq; unsigned long x; - swim3_dbg("start request, initial state=%d\n", fs->state); - - if (fs->state == idle && fs->wanted) { - fs->state = available; - wake_up(&fs->wait); - return; + spin_lock_irq(&swim3_lock); + if (fs->cur_req || fs->state != idle) { + spin_unlock_irq(&swim3_lock); + return BLK_STS_DEV_RESOURCE; } - while (fs->state == idle) { - swim3_dbg("start request, idle loop, cur_req=%p\n", fs->cur_req); - if (!fs->cur_req) { - fs->cur_req = blk_fetch_request(disks[fs->index]->queue); - swim3_dbg(" fetched request %p\n", fs->cur_req); - if (!fs->cur_req) - break; - } - req = fs->cur_req; - - if (fs->mdev->media_bay && - check_media_bay(fs->mdev->media_bay) != MB_FD) { - swim3_dbg("%s", " media bay absent, dropping req\n"); - swim3_end_request(fs, BLK_STS_IOERR, 0); - continue; - } - -#if 0 /* This is really too verbose */ - swim3_dbg("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%u buf=%p\n", - req->rq_disk->disk_name, req->cmd, - (long)blk_rq_pos(req), blk_rq_sectors(req), - bio_data(req->bio)); - swim3_dbg(" current_nr_sectors=%u\n", - blk_rq_cur_sectors(req)); -#endif - - if (blk_rq_pos(req) >= fs->total_secs) { - swim3_dbg(" pos out of bounds (%ld, max is %ld)\n", - (long)blk_rq_pos(req), (long)fs->total_secs); - swim3_end_request(fs, BLK_STS_IOERR, 0); - continue; - } - if (fs->ejected) { - swim3_dbg("%s", " disk ejected\n"); + blk_mq_start_request(req); + fs->cur_req = req; + if (fs->mdev->media_bay && + check_media_bay(fs->mdev->media_bay) != MB_FD) { + swim3_dbg("%s", " media bay absent, dropping req\n"); + swim3_end_request(fs, BLK_STS_IOERR, 0); + goto out; + } + if (fs->ejected) { + swim3_dbg("%s", " disk ejected\n"); + swim3_end_request(fs, BLK_STS_IOERR, 0); + goto out; + } + if (rq_data_dir(req) == WRITE) { + if (fs->write_prot < 0) + fs->write_prot = swim3_readbit(fs, WRITE_PROT); + if (fs->write_prot) { + swim3_dbg("%s", " try to write, disk write protected\n"); swim3_end_request(fs, BLK_STS_IOERR, 0); - continue; - } - - if (rq_data_dir(req) == WRITE) { - if (fs->write_prot < 0) - fs->write_prot = swim3_readbit(fs, WRITE_PROT); - if (fs->write_prot) { - swim3_dbg("%s", " try to write, disk write protected\n"); - swim3_end_request(fs, BLK_STS_IOERR, 0); - continue; - } + goto out; } - - /* Do not remove the cast. blk_rq_pos(req) is now a - * sector_t and can be 64 bits, but it will never go - * past 32 bits for this driver anyway, so we can - * safely cast it down and not have to do a 64/32 - * division - */ - fs->req_cyl = ((long)blk_rq_pos(req)) / fs->secpercyl; - x = ((long)blk_rq_pos(req)) % fs->secpercyl; - fs->head = x / fs->secpertrack; - fs->req_sector = x % fs->secpertrack + 1; - fs->state = do_transfer; - fs->retries = 0; - - act(fs); } -} -static void do_fd_request(struct request_queue * q) -{ - start_request(q->queuedata); + /* + * Do not remove the cast. blk_rq_pos(req) is now a sector_t and can be + * 64 bits, but it will never go past 32 bits for this driver anyway, so + * we can safely cast it down and not have to do a 64/32 division + */ + fs->req_cyl = ((long)blk_rq_pos(req)) / fs->secpercyl; + x = ((long)blk_rq_pos(req)) % fs->secpercyl; + fs->head = x / fs->secpertrack; + fs->req_sector = x % fs->secpertrack + 1; + fs->state = do_transfer; + fs->retries = 0; + + act(fs); + +out: + spin_unlock_irq(&swim3_lock); + return BLK_STS_OK; } static void set_timeout(struct floppy_state *fs, int nticks, @@ -585,7 +557,6 @@ static void scan_timeout(struct timer_list *t) if (fs->retries > 5) { swim3_end_request(fs, BLK_STS_IOERR, 0); fs->state = idle; - start_request(fs); } else { fs->state = jogging; act(fs); @@ -609,7 +580,6 @@ static void seek_timeout(struct timer_list *t) swim3_err("%s", "Seek timeout\n"); swim3_end_request(fs, BLK_STS_IOERR, 0); fs->state = idle; - start_request(fs); spin_unlock_irqrestore(&swim3_lock, flags); } @@ -638,7 +608,6 @@ static void settle_timeout(struct timer_list *t) swim3_err("%s", "Seek settle timeout\n"); swim3_end_request(fs, BLK_STS_IOERR, 0); fs->state = idle; - start_request(fs); unlock: spin_unlock_irqrestore(&swim3_lock, flags); } @@ -667,7 +636,6 @@ static void xfer_timeout(struct timer_list *t) (long)blk_rq_pos(fs->cur_req)); swim3_end_request(fs, BLK_STS_IOERR, 0); fs->state = idle; - start_request(fs); spin_unlock_irqrestore(&swim3_lock, flags); } @@ -704,7 +672,6 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) if (fs->retries > 5) { swim3_end_request(fs, BLK_STS_IOERR, 0); fs->state = idle; - start_request(fs); } else { fs->state = jogging; act(fs); @@ -796,7 +763,6 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) fs->state, rq_data_dir(req), intr, err); swim3_end_request(fs, BLK_STS_IOERR, 0); fs->state = idle; - start_request(fs); break; } fs->retries = 0; @@ -813,8 +779,6 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) } else fs->state = idle; } - if (fs->state == idle) - start_request(fs); break; default: swim3_err("Don't know what to do in state %d\n", fs->state); @@ -862,14 +826,19 @@ static int grab_drive(struct floppy_state *fs, enum swim_state state, static void release_drive(struct floppy_state *fs) { + struct request_queue *q = disks[fs->index]->queue; unsigned long flags; swim3_dbg("%s", "-> release drive\n"); spin_lock_irqsave(&swim3_lock, flags); fs->state = idle; - start_request(fs); spin_unlock_irqrestore(&swim3_lock, flags); + + blk_mq_freeze_queue(q); + blk_mq_quiesce_queue(q); + blk_mq_unquiesce_queue(q); + blk_mq_unfreeze_queue(q); } static int fd_eject(struct floppy_state *fs) @@ -1089,6 +1058,10 @@ static const struct block_device_operations floppy_fops = { .revalidate_disk= floppy_revalidate, }; +static const struct blk_mq_ops swim3_mq_ops = { + .queue_rq = swim3_queue_rq, +}; + static void swim3_mb_event(struct macio_dev* mdev, int mb_state) { struct floppy_state *fs = macio_get_drvdata(mdev); @@ -1222,9 +1195,12 @@ static int swim3_attach(struct macio_dev *mdev, rc = -ENOMEM; goto out_unregister; } - disk->queue = blk_init_queue(do_fd_request, &swim3_lock); - if (disk->queue == NULL) { - rc = -ENOMEM; + + disk->queue = blk_mq_init_sq_queue(&fs->tag_set, &swim3_mq_ops, 2, + BLK_MQ_F_SHOULD_MERGE); + if (IS_ERR(disk->queue)) { + rc = PTR_ERR(disk->queue); + disk->queue = NULL; goto out_put_disk; } blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH); @@ -1249,6 +1225,7 @@ static int swim3_attach(struct macio_dev *mdev, out_cleanup_queue: blk_cleanup_queue(disk->queue); disk->queue = NULL; + blk_mq_free_tag_set(&fs->tag_set); out_put_disk: put_disk(disk); out_unregister: -- cgit v1.2.3 From c87228f16f0acdf242dee62f139013212208473f Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Thu, 11 Oct 2018 12:20:45 -0700 Subject: amiflop: fold headers into C file amifd.h and amifdreg.h are only used from amiflop.c, and they're pretty small, so move the contents to amiflop.c and get rid of the .h files. This is preparation for adding a struct blk_mq_tag_set to struct amiga_floppy_struct. Signed-off-by: Omar Sandoval Signed-off-by: Jens Axboe --- drivers/block/amiflop.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 120 insertions(+), 3 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index 3aaf6af3ec23..a7d6e6a9b12f 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -61,10 +61,8 @@ #include #include #include -#include -#include #include -#include +#include #include #include #include @@ -86,6 +84,125 @@ * Defines */ +/* + * CIAAPRA bits (read only) + */ + +#define DSKRDY (0x1<<5) /* disk ready when low */ +#define DSKTRACK0 (0x1<<4) /* head at track zero when low */ +#define DSKPROT (0x1<<3) /* disk protected when low */ +#define DSKCHANGE (0x1<<2) /* low when disk removed */ + +/* + * CIAAPRB bits (read/write) + */ + +#define DSKMOTOR (0x1<<7) /* motor on when low */ +#define DSKSEL3 (0x1<<6) /* select drive 3 when low */ +#define DSKSEL2 (0x1<<5) /* select drive 2 when low */ +#define DSKSEL1 (0x1<<4) /* select drive 1 when low */ +#define DSKSEL0 (0x1<<3) /* select drive 0 when low */ +#define DSKSIDE (0x1<<2) /* side selection: 0 = upper, 1 = lower */ +#define DSKDIREC (0x1<<1) /* step direction: 0=in, 1=out (to trk 0) */ +#define DSKSTEP (0x1) /* pulse low to step head 1 track */ + +/* + * DSKBYTR bits (read only) + */ + +#define DSKBYT (1<<15) /* register contains valid byte when set */ +#define DMAON (1<<14) /* disk DMA enabled */ +#define DISKWRITE (1<<13) /* disk write bit in DSKLEN enabled */ +#define WORDEQUAL (1<<12) /* DSKSYNC register match when true */ +/* bits 7-0 are data */ + +/* + * ADKCON/ADKCONR bits + */ + +#ifndef SETCLR +#define ADK_SETCLR (1<<15) /* control bit */ +#endif +#define ADK_PRECOMP1 (1<<14) /* precompensation selection */ +#define ADK_PRECOMP0 (1<<13) /* 00=none, 01=140ns, 10=280ns, 11=500ns */ +#define ADK_MFMPREC (1<<12) /* 0=GCR precomp., 1=MFM precomp. */ +#define ADK_WORDSYNC (1<<10) /* enable DSKSYNC auto DMA */ +#define ADK_MSBSYNC (1<<9) /* when 1, enable sync on MSbit (for GCR) */ +#define ADK_FAST (1<<8) /* bit cell: 0=2us (GCR), 1=1us (MFM) */ + +/* + * DSKLEN bits + */ + +#define DSKLEN_DMAEN (1<<15) +#define DSKLEN_WRITE (1<<14) + +/* + * INTENA/INTREQ bits + */ + +#define DSKINDEX (0x1<<4) /* DSKINDEX bit */ + +/* + * Misc + */ + +#define MFM_SYNC 0x4489 /* standard MFM sync value */ + +/* Values for FD_COMMAND */ +#define FD_RECALIBRATE 0x07 /* move to track 0 */ +#define FD_SEEK 0x0F /* seek track */ +#define FD_READ 0xE6 /* read with MT, MFM, SKip deleted */ +#define FD_WRITE 0xC5 /* write with MT, MFM */ +#define FD_SENSEI 0x08 /* Sense Interrupt Status */ +#define FD_SPECIFY 0x03 /* specify HUT etc */ +#define FD_FORMAT 0x4D /* format one track */ +#define FD_VERSION 0x10 /* get version code */ +#define FD_CONFIGURE 0x13 /* configure FIFO operation */ +#define FD_PERPENDICULAR 0x12 /* perpendicular r/w mode */ + +#define FD_MAX_UNITS 4 /* Max. Number of drives */ +#define FLOPPY_MAX_SECTORS 22 /* Max. Number of sectors per track */ + +struct fd_data_type { + char *name; /* description of data type */ + int sects; /* sectors per track */ + int (*read_fkt)(int); /* read whole track */ + void (*write_fkt)(int); /* write whole track */ +}; + +struct fd_drive_type { + unsigned long code; /* code returned from drive */ + char *name; /* description of drive */ + unsigned int tracks; /* number of tracks */ + unsigned int heads; /* number of heads */ + unsigned int read_size; /* raw read size for one track */ + unsigned int write_size; /* raw write size for one track */ + unsigned int sect_mult; /* sectors and gap multiplier (HD = 2) */ + unsigned int precomp1; /* start track for precomp 1 */ + unsigned int precomp2; /* start track for precomp 2 */ + unsigned int step_delay; /* time (in ms) for delay after step */ + unsigned int settle_time; /* time to settle after dir change */ + unsigned int side_time; /* time needed to change sides */ +}; + +struct amiga_floppy_struct { + struct fd_drive_type *type; /* type of floppy for this unit */ + struct fd_data_type *dtype; /* type of floppy for this unit */ + int track; /* current track (-1 == unknown) */ + unsigned char *trackbuf; /* current track (kmaloc()'d */ + + int blocks; /* total # blocks on disk */ + + int changed; /* true when not known */ + int disk; /* disk in drive (-1 == unknown) */ + int motor; /* true when motor is at speed */ + int busy; /* true when drive is active */ + int dirty; /* true when trackbuf is not on disk */ + int status; /* current error code for unit */ + struct gendisk *gendisk; +}; + /* * Error codes */ -- cgit v1.2.3 From 53d0f8dbde89cf6c862c7a62e00c6123e02cba41 Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Thu, 11 Oct 2018 12:20:46 -0700 Subject: amiflop: clean up on errors during setup The error handling in fd_probe_drives() doesn't clean up at all. Fix it up in preparation for converting to blk-mq. While we're here, get rid of the commented out amiga_floppy_remove(). Signed-off-by: Omar Sandoval Signed-off-by: Jens Axboe --- drivers/block/amiflop.c | 84 +++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 44 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index a7d6e6a9b12f..eef3b085e70a 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -1818,11 +1818,41 @@ static const struct block_device_operations floppy_fops = { .check_events = amiga_check_events, }; +static struct gendisk *fd_alloc_disk(int drive) +{ + struct gendisk *disk; + + disk = alloc_disk(1); + if (!disk) + goto out; + + disk->queue = blk_init_queue(do_fd_request, &amiflop_lock); + if (IS_ERR(disk->queue)) { + disk->queue = NULL; + goto out_put_disk; + } + + unit[drive].trackbuf = kmalloc(FLOPPY_MAX_SECTORS * 512, GFP_KERNEL); + if (!unit[drive].trackbuf) + goto out_cleanup_queue; + + return disk; + +out_cleanup_queue: + blk_cleanup_queue(disk->queue); + disk->queue = NULL; +out_put_disk: + put_disk(disk); +out: + unit[drive].type->code = FD_NODRIVE; + return NULL; +} + static int __init fd_probe_drives(void) { int drive,drives,nomem; - printk(KERN_INFO "FD: probing units\nfound "); + pr_info("FD: probing units\nfound"); drives=0; nomem=0; for(drive=0;drivecode == FD_NODRIVE) continue; - disk = alloc_disk(1); + + disk = fd_alloc_disk(drive); if (!disk) { - unit[drive].type->code = FD_NODRIVE; + pr_cont(" no mem for fd%d", drive); + nomem = 1; continue; } unit[drive].gendisk = disk; - - disk->queue = blk_init_queue(do_fd_request, &amiflop_lock); - if (!disk->queue) { - unit[drive].type->code = FD_NODRIVE; - continue; - } - drives++; - if ((unit[drive].trackbuf = kmalloc(FLOPPY_MAX_SECTORS * 512, GFP_KERNEL)) == NULL) { - printk("no mem for "); - unit[drive].type = &drive_types[num_dr_types - 1]; /* FD_NODRIVE */ - drives--; - nomem = 1; - } - printk("fd%d ",drive); + + pr_cont(" fd%d",drive); disk->major = FLOPPY_MAJOR; disk->first_minor = drive; disk->fops = &floppy_fops; @@ -1861,11 +1881,11 @@ static int __init fd_probe_drives(void) } if ((drives > 0) || (nomem == 0)) { if (drives == 0) - printk("no drives"); - printk("\n"); + pr_cont(" no drives"); + pr_cont("\n"); return drives; } - printk("\n"); + pr_cont("\n"); return -ENOMEM; } @@ -1948,30 +1968,6 @@ out_blkdev: return ret; } -#if 0 /* not safe to unload */ -static int __exit amiga_floppy_remove(struct platform_device *pdev) -{ - int i; - - for( i = 0; i < FD_MAX_UNITS; i++) { - if (unit[i].type->code != FD_NODRIVE) { - struct request_queue *q = unit[i].gendisk->queue; - del_gendisk(unit[i].gendisk); - put_disk(unit[i].gendisk); - kfree(unit[i].trackbuf); - if (q) - blk_cleanup_queue(q); - } - } - blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); - free_irq(IRQ_AMIGA_CIAA_TB, NULL); - free_irq(IRQ_AMIGA_DSKBLK, NULL); - custom.dmacon = DMAF_DISK; /* disable DMA */ - amiga_chip_free(raw_buf); - unregister_blkdev(FLOPPY_MAJOR, "fd"); -} -#endif - static struct platform_driver amiga_floppy_driver = { .driver = { .name = "amiga-floppy", -- cgit v1.2.3 From 21b07f35544af5e2c11f079057e8fb4263d35dd3 Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Mon, 15 Oct 2018 09:16:37 -0600 Subject: amiflop: convert to blk-mq Straightforward conversion, just use the existing amiflop_lock to serialize access to the controller. Compile-tested only. Cc: Laurent Vivier Signed-off-by: Omar Sandoval Converted to blk_mq_init_sq_queue() Signed-off-by: Jens Axboe --- drivers/block/amiflop.c | 113 +++++++++++++++--------------------------------- 1 file changed, 35 insertions(+), 78 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index eef3b085e70a..bf996bd44cfc 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -201,6 +201,7 @@ struct amiga_floppy_struct { int dirty; /* true when trackbuf is not on disk */ int status; /* current error code for unit */ struct gendisk *gendisk; + struct blk_mq_tag_set tag_set; }; /* @@ -281,7 +282,6 @@ static volatile int selected = -1; /* currently selected drive */ static int writepending; static int writefromint; static char *raw_buf; -static int fdc_queue; static DEFINE_SPINLOCK(amiflop_lock); @@ -1454,76 +1454,20 @@ static int get_track(int drive, int track) return -1; } -/* - * Round-robin between our available drives, doing one request from each - */ -static struct request *set_next_request(void) +static blk_status_t amiflop_rw_cur_segment(struct amiga_floppy_struct *floppy, + struct request *rq) { - struct request_queue *q; - int cnt = FD_MAX_UNITS; - struct request *rq = NULL; - - /* Find next queue we can dispatch from */ - fdc_queue = fdc_queue + 1; - if (fdc_queue == FD_MAX_UNITS) - fdc_queue = 0; - - for(cnt = FD_MAX_UNITS; cnt > 0; cnt--) { - - if (unit[fdc_queue].type->code == FD_NODRIVE) { - if (++fdc_queue == FD_MAX_UNITS) - fdc_queue = 0; - continue; - } - - q = unit[fdc_queue].gendisk->queue; - if (q) { - rq = blk_fetch_request(q); - if (rq) - break; - } - - if (++fdc_queue == FD_MAX_UNITS) - fdc_queue = 0; - } - - return rq; -} - -static void redo_fd_request(void) -{ - struct request *rq; + int drive = floppy - unit; unsigned int cnt, block, track, sector; - int drive; - struct amiga_floppy_struct *floppy; char *data; - unsigned long flags; - blk_status_t err; -next_req: - rq = set_next_request(); - if (!rq) { - /* Nothing left to do */ - return; - } - - floppy = rq->rq_disk->private_data; - drive = floppy - unit; - -next_segment: - /* Here someone could investigate to be more efficient */ - for (cnt = 0, err = BLK_STS_OK; cnt < blk_rq_cur_sectors(rq); cnt++) { + for (cnt = 0; cnt < blk_rq_cur_sectors(rq); cnt++) { #ifdef DEBUG printk("fd: sector %ld + %d requested for %s\n", blk_rq_pos(rq), cnt, (rq_data_dir(rq) == READ) ? "read" : "write"); #endif block = blk_rq_pos(rq) + cnt; - if ((int)block > floppy->blocks) { - err = BLK_STS_IOERR; - break; - } - track = block / (floppy->dtype->sects * floppy->type->sect_mult); sector = block % (floppy->dtype->sects * floppy->type->sect_mult); data = bio_data(rq->bio) + 512 * cnt; @@ -1532,10 +1476,8 @@ next_segment: "0x%08lx\n", track, sector, data); #endif - if (get_track(drive, track) == -1) { - err = BLK_STS_IOERR; - break; - } + if (get_track(drive, track) == -1) + return BLK_STS_IOERR; if (rq_data_dir(rq) == READ) { memcpy(data, floppy->trackbuf + sector * 512, 512); @@ -1543,31 +1485,40 @@ next_segment: memcpy(floppy->trackbuf + sector * 512, data, 512); /* keep the drive spinning while writes are scheduled */ - if (!fd_motor_on(drive)) { - err = BLK_STS_IOERR; - break; - } + if (!fd_motor_on(drive)) + return BLK_STS_IOERR; /* * setup a callback to write the track buffer * after a short (1 tick) delay. */ - local_irq_save(flags); - floppy->dirty = 1; /* reset the timer */ mod_timer (flush_track_timer + drive, jiffies + 1); - local_irq_restore(flags); } } - if (__blk_end_request_cur(rq, err)) - goto next_segment; - goto next_req; + return BLK_STS_OK; } -static void do_fd_request(struct request_queue * q) +static blk_status_t amiflop_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { - redo_fd_request(); + struct request *rq = bd->rq; + struct amiga_floppy_struct *floppy = rq->rq_disk->private_data; + blk_status_t err; + + if (!spin_trylock_irq(&amiflop_lock)) + return BLK_STS_DEV_RESOURCE; + + blk_mq_start_request(rq); + + do { + err = amiflop_rw_cur_segment(floppy, rq); + } while (blk_update_request(rq, err, blk_rq_cur_bytes(rq))); + blk_mq_end_request(rq, err); + + spin_unlock_irq(&amiflop_lock); + return BLK_STS_OK; } static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo) @@ -1818,6 +1769,10 @@ static const struct block_device_operations floppy_fops = { .check_events = amiga_check_events, }; +static const struct blk_mq_ops amiflop_mq_ops = { + .queue_rq = amiflop_queue_rq, +}; + static struct gendisk *fd_alloc_disk(int drive) { struct gendisk *disk; @@ -1826,7 +1781,8 @@ static struct gendisk *fd_alloc_disk(int drive) if (!disk) goto out; - disk->queue = blk_init_queue(do_fd_request, &amiflop_lock); + disk->queue = blk_mq_init_sq_queue(&unit[drive].tag_set, &amiflop_mq_ops, + 2, BLK_MQ_F_SHOULD_MERGE); if (IS_ERR(disk->queue)) { disk->queue = NULL; goto out_put_disk; @@ -1841,6 +1797,7 @@ static struct gendisk *fd_alloc_disk(int drive) out_cleanup_queue: blk_cleanup_queue(disk->queue); disk->queue = NULL; + blk_mq_free_tag_set(&unit[drive].tag_set); out_put_disk: put_disk(disk); out: -- cgit v1.2.3 From 3e6b8c3c4b14f4f0c4a74027156eb31544c0b0da Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Thu, 11 Oct 2018 12:20:48 -0700 Subject: ataflop: fold headers into C file atafd.h and atafdreg.h are only used from ataflop.c, so merge them in there. Signed-off-by: Omar Sandoval Signed-off-by: Jens Axboe --- drivers/block/ataflop.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 2 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index dfb2c2622e5a..17df631c5d85 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -71,8 +71,6 @@ #include #include -#include -#include #include #include #include @@ -85,6 +83,87 @@ static DEFINE_MUTEX(ataflop_mutex); static struct request *fd_request; static int fdc_queue; +/* + * WD1772 stuff + */ + +/* register codes */ + +#define FDCSELREG_STP (0x80) /* command/status register */ +#define FDCSELREG_TRA (0x82) /* track register */ +#define FDCSELREG_SEC (0x84) /* sector register */ +#define FDCSELREG_DTA (0x86) /* data register */ + +/* register names for FDC_READ/WRITE macros */ + +#define FDCREG_CMD 0 +#define FDCREG_STATUS 0 +#define FDCREG_TRACK 2 +#define FDCREG_SECTOR 4 +#define FDCREG_DATA 6 + +/* command opcodes */ + +#define FDCCMD_RESTORE (0x00) /* - */ +#define FDCCMD_SEEK (0x10) /* | */ +#define FDCCMD_STEP (0x20) /* | TYP 1 Commands */ +#define FDCCMD_STIN (0x40) /* | */ +#define FDCCMD_STOT (0x60) /* - */ +#define FDCCMD_RDSEC (0x80) /* - TYP 2 Commands */ +#define FDCCMD_WRSEC (0xa0) /* - " */ +#define FDCCMD_RDADR (0xc0) /* - */ +#define FDCCMD_RDTRA (0xe0) /* | TYP 3 Commands */ +#define FDCCMD_WRTRA (0xf0) /* - */ +#define FDCCMD_FORCI (0xd0) /* - TYP 4 Command */ + +/* command modifier bits */ + +#define FDCCMDADD_SR6 (0x00) /* step rate settings */ +#define FDCCMDADD_SR12 (0x01) +#define FDCCMDADD_SR2 (0x02) +#define FDCCMDADD_SR3 (0x03) +#define FDCCMDADD_V (0x04) /* verify */ +#define FDCCMDADD_H (0x08) /* wait for spin-up */ +#define FDCCMDADD_U (0x10) /* update track register */ +#define FDCCMDADD_M (0x10) /* multiple sector access */ +#define FDCCMDADD_E (0x04) /* head settling flag */ +#define FDCCMDADD_P (0x02) /* precompensation off */ +#define FDCCMDADD_A0 (0x01) /* DAM flag */ + +/* status register bits */ + +#define FDCSTAT_MOTORON (0x80) /* motor on */ +#define FDCSTAT_WPROT (0x40) /* write protected (FDCCMD_WR*) */ +#define FDCSTAT_SPINUP (0x20) /* motor speed stable (Type I) */ +#define FDCSTAT_DELDAM (0x20) /* sector has deleted DAM (Type II+III) */ +#define FDCSTAT_RECNF (0x10) /* record not found */ +#define FDCSTAT_CRC (0x08) /* CRC error */ +#define FDCSTAT_TR00 (0x04) /* Track 00 flag (Type I) */ +#define FDCSTAT_LOST (0x04) /* Lost Data (Type II+III) */ +#define FDCSTAT_IDX (0x02) /* Index status (Type I) */ +#define FDCSTAT_DRQ (0x02) /* DRQ status (Type II+III) */ +#define FDCSTAT_BUSY (0x01) /* FDC is busy */ + + +/* PSG Port A Bit Nr 0 .. Side Sel .. 0 -> Side 1 1 -> Side 2 */ +#define DSKSIDE (0x01) + +#define DSKDRVNONE (0x06) +#define DSKDRV0 (0x02) +#define DSKDRV1 (0x04) + +/* step rates */ +#define FDCSTEP_6 0x00 +#define FDCSTEP_12 0x01 +#define FDCSTEP_2 0x02 +#define FDCSTEP_3 0x03 + +struct atari_format_descr { + int track; /* to be formatted */ + int head; /* "" "" */ + int sect_offset; /* offset of first sector */ +}; + /* Disk types: DD, HD, ED */ static struct atari_disk_type { const char *name; -- cgit v1.2.3 From 71327f547ee3a46ec5c39fdbbd268401b2578d0e Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Thu, 11 Oct 2018 12:20:49 -0700 Subject: ataflop: fix error handling during setup Move queue allocation next to disk allocation to fix a couple of issues: - If add_disk() hasn't been called, we should clear disk->queue before calling put_disk(). - If we fail to allocate a request queue, we still need to put all of the disks, not just the ones that we allocated queues for. Signed-off-by: Omar Sandoval Signed-off-by: Jens Axboe --- drivers/block/ataflop.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index 17df631c5d85..0144d598ac47 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -2014,6 +2014,11 @@ static int __init atari_floppy_init (void) unit[i].disk = alloc_disk(1); if (!unit[i].disk) goto Enomem; + + unit[i].disk->queue = blk_init_queue(do_fd_request, + &ataflop_lock); + if (!unit[i].disk->queue) + goto Enomem; } if (UseTrackbuffer < 0) @@ -2045,10 +2050,6 @@ static int __init atari_floppy_init (void) sprintf(unit[i].disk->disk_name, "fd%d", i); unit[i].disk->fops = &floppy_fops; unit[i].disk->private_data = &unit[i]; - unit[i].disk->queue = blk_init_queue(do_fd_request, - &ataflop_lock); - if (!unit[i].disk->queue) - goto Enomem; set_capacity(unit[i].disk, MAX_DISK_SIZE * 2); add_disk(unit[i].disk); } @@ -2063,13 +2064,17 @@ static int __init atari_floppy_init (void) return 0; Enomem: - while (i--) { - struct request_queue *q = unit[i].disk->queue; + do { + struct gendisk *disk = unit[i].disk; - put_disk(unit[i].disk); - if (q) - blk_cleanup_queue(q); - } + if (disk) { + if (disk->queue) { + blk_cleanup_queue(disk->queue); + disk->queue = NULL; + } + put_disk(unit[i].disk); + } + } while (i--); unregister_blkdev(FLOPPY_MAJOR, "fd"); return -ENOMEM; -- cgit v1.2.3 From 6ec3938cff95fe792a05fdf4ba14f92977e5e31d Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Mon, 15 Oct 2018 09:18:24 -0600 Subject: ataflop: convert to blk-mq This driver is already pretty broken, in that it has two wait_events() (one in stdma_lock()) in request_fn. Get rid of the first one by freezing/quiescing the queue on format, and the second one by replacing it with stdma_try_lock(). The rest is straightforward. Compile-tested only and probably incorrect. Cc: Laurent Vivier Signed-off-by: Omar Sandoval Converted to blk_mq_init_sq_queue() Signed-off-by: Jens Axboe --- drivers/block/ataflop.c | 173 ++++++++++++++++++++---------------------------- 1 file changed, 71 insertions(+), 102 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index 0144d598ac47..f88b4c26d422 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -66,7 +66,7 @@ #include #include #include -#include +#include #include #include #include @@ -81,7 +81,6 @@ static DEFINE_MUTEX(ataflop_mutex); static struct request *fd_request; -static int fdc_queue; /* * WD1772 stuff @@ -300,6 +299,7 @@ static struct atari_floppy_struct { struct gendisk *disk; int ref; int type; + struct blk_mq_tag_set tag_set; } unit[FD_MAX_UNITS]; #define UD unit[drive] @@ -379,9 +379,6 @@ static int IsFormatting = 0, FormatError; static int UserSteprate[FD_MAX_UNITS] = { -1, -1 }; module_param_array(UserSteprate, int, NULL, 0); -/* Synchronization of FDC access. */ -static volatile int fdc_busy = 0; -static DECLARE_WAIT_QUEUE_HEAD(fdc_wait); static DECLARE_COMPLETION(format_wait); static unsigned long changed_floppies = 0xff, fake_change = 0; @@ -441,7 +438,6 @@ static void fd_times_out(struct timer_list *unused); static void finish_fdc( void ); static void finish_fdc_done( int dummy ); static void setup_req_params( int drive ); -static void redo_fd_request( void); static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long param); static void fd_probe( int drive ); @@ -459,8 +455,11 @@ static DEFINE_TIMER(fd_timer, check_change); static void fd_end_request_cur(blk_status_t err) { - if (!__blk_end_request_cur(fd_request, err)) + if (!blk_update_request(fd_request, err, + blk_rq_cur_bytes(fd_request))) { + __blk_mq_end_request(fd_request, err); fd_request = NULL; + } } static inline void start_motor_off_timer(void) @@ -706,7 +705,6 @@ static void fd_error( void ) if (SelectedDrive != -1) SUD.track = -1; } - redo_fd_request(); } @@ -724,14 +722,15 @@ static void fd_error( void ) static int do_format(int drive, int type, struct atari_format_descr *desc) { + struct request_queue *q = unit[drive].disk->queue; unsigned char *p; int sect, nsect; unsigned long flags; + int ret; - DPRINT(("do_format( dr=%d tr=%d he=%d offs=%d )\n", - drive, desc->track, desc->head, desc->sect_offset )); + blk_mq_freeze_queue(q); + blk_mq_quiesce_queue(q); - wait_event(fdc_wait, cmpxchg(&fdc_busy, 0, 1) == 0); local_irq_save(flags); stdma_lock(floppy_irq, NULL); atari_turnon_irq( IRQ_MFP_FDC ); /* should be already, just to be sure */ @@ -740,16 +739,16 @@ static int do_format(int drive, int type, struct atari_format_descr *desc) if (type) { if (--type >= NUM_DISK_MINORS || minor2disktype[type].drive_types > DriveType) { - redo_fd_request(); - return -EINVAL; + ret = -EINVAL; + goto out; } type = minor2disktype[type].index; UDT = &atari_disk_type[type]; } if (!UDT || desc->track >= UDT->blocks/UDT->spt/2 || desc->head >= 2) { - redo_fd_request(); - return -EINVAL; + ret = -EINVAL; + goto out; } nsect = UDT->spt; @@ -788,8 +787,11 @@ static int do_format(int drive, int type, struct atari_format_descr *desc) wait_for_completion(&format_wait); - redo_fd_request(); - return( FormatError ? -EIO : 0 ); + ret = FormatError ? -EIO : 0; +out: + blk_mq_unquiesce_queue(q); + blk_mq_unfreeze_queue(q); + return ret; } @@ -819,7 +821,6 @@ static void do_fd_action( int drive ) else { /* all sectors finished */ fd_end_request_cur(BLK_STS_OK); - redo_fd_request(); return; } } @@ -1224,7 +1225,6 @@ static void fd_rwsec_done1(int status) else { /* all sectors finished */ fd_end_request_cur(BLK_STS_OK); - redo_fd_request(); } return; @@ -1382,8 +1382,6 @@ static void finish_fdc_done( int dummy ) local_irq_save(flags); stdma_release(); - fdc_busy = 0; - wake_up( &fdc_wait ); local_irq_restore(flags); DPRINT(("finish_fdc() finished\n")); @@ -1473,59 +1471,34 @@ static void setup_req_params( int drive ) ReqTrack, ReqSector, (unsigned long)ReqData )); } -/* - * Round-robin between our available drives, doing one request from each - */ -static struct request *set_next_request(void) +static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { - struct request_queue *q; - int old_pos = fdc_queue; - struct request *rq = NULL; - - do { - q = unit[fdc_queue].disk->queue; - if (++fdc_queue == FD_MAX_UNITS) - fdc_queue = 0; - if (q) { - rq = blk_fetch_request(q); - if (rq) { - rq->error_count = 0; - break; - } - } - } while (fdc_queue != old_pos); - - return rq; -} - + struct atari_floppy_struct *floppy = bd->rq->rq_disk->private_data; + int drive = floppy - unit; + int type = floppy->type; -static void redo_fd_request(void) -{ - int drive, type; - struct atari_floppy_struct *floppy; + spin_lock_irq(&ataflop_lock); + if (fd_request) { + spin_unlock_irq(&ataflop_lock); + return BLK_STS_DEV_RESOURCE; + } + if (!stdma_try_lock(floppy_irq, NULL)) { + spin_unlock_irq(&ataflop_lock); + return BLK_STS_RESOURCE; + } + fd_request = bd->rq; + blk_mq_start_request(fd_request); - DPRINT(("redo_fd_request: fd_request=%p dev=%s fd_request->sector=%ld\n", - fd_request, fd_request ? fd_request->rq_disk->disk_name : "", - fd_request ? blk_rq_pos(fd_request) : 0 )); + atari_disable_irq( IRQ_MFP_FDC ); IsFormatting = 0; -repeat: - if (!fd_request) { - fd_request = set_next_request(); - if (!fd_request) - goto the_end; - } - - floppy = fd_request->rq_disk->private_data; - drive = floppy - unit; - type = floppy->type; - if (!UD.connected) { /* drive not connected */ printk(KERN_ERR "Unknown Device: fd%d\n", drive ); fd_end_request_cur(BLK_STS_IOERR); - goto repeat; + goto out; } if (type == 0) { @@ -1541,23 +1514,18 @@ repeat: if (--type >= NUM_DISK_MINORS) { printk(KERN_WARNING "fd%d: invalid disk format", drive ); fd_end_request_cur(BLK_STS_IOERR); - goto repeat; + goto out; } if (minor2disktype[type].drive_types > DriveType) { printk(KERN_WARNING "fd%d: unsupported disk format", drive ); fd_end_request_cur(BLK_STS_IOERR); - goto repeat; + goto out; } type = minor2disktype[type].index; UDT = &atari_disk_type[type]; set_capacity(floppy->disk, UDT->blocks); UD.autoprobe = 0; } - - if (blk_rq_pos(fd_request) + 1 > UDT->blocks) { - fd_end_request_cur(BLK_STS_IOERR); - goto repeat; - } /* stop deselect timer */ del_timer( &motor_off_timer ); @@ -1569,22 +1537,13 @@ repeat: setup_req_params( drive ); do_fd_action( drive ); - return; - - the_end: - finish_fdc(); -} - - -void do_fd_request(struct request_queue * q) -{ - DPRINT(("do_fd_request for pid %d\n",current->pid)); - wait_event(fdc_wait, cmpxchg(&fdc_busy, 0, 1) == 0); - stdma_lock(floppy_irq, NULL); - - atari_disable_irq( IRQ_MFP_FDC ); - redo_fd_request(); + if (bd->last) + finish_fdc(); atari_enable_irq( IRQ_MFP_FDC ); + +out: + spin_unlock_irq(&ataflop_lock); + return BLK_STS_OK; } static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, @@ -1662,7 +1621,6 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, /* what if type > 0 here? Overwrite specified entry ? */ if (type) { /* refuse to re-set a predefined type for now */ - redo_fd_request(); return -EINVAL; } @@ -1730,10 +1688,8 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, /* sanity check */ if (setprm.track != dtp->blocks/dtp->spt/2 || - setprm.head != 2) { - redo_fd_request(); + setprm.head != 2) return -EINVAL; - } UDT = dtp; set_capacity(floppy->disk, UDT->blocks); @@ -1989,6 +1945,10 @@ static const struct block_device_operations floppy_fops = { .revalidate_disk= floppy_revalidate, }; +static const struct blk_mq_ops ataflop_mq_ops = { + .queue_rq = ataflop_queue_rq, +}; + static struct kobject *floppy_find(dev_t dev, int *part, void *data) { int drive = *part & 3; @@ -2002,6 +1962,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data) static int __init atari_floppy_init (void) { int i; + int ret; if (!MACH_IS_ATARI) /* Amiga, Mac, ... don't have Atari-compatible floppy :-) */ @@ -2012,13 +1973,19 @@ static int __init atari_floppy_init (void) for (i = 0; i < FD_MAX_UNITS; i++) { unit[i].disk = alloc_disk(1); - if (!unit[i].disk) - goto Enomem; + if (!unit[i].disk) { + ret = -ENOMEM; + goto err; + } - unit[i].disk->queue = blk_init_queue(do_fd_request, - &ataflop_lock); - if (!unit[i].disk->queue) - goto Enomem; + unit[i].disk->queue = blk_mq_init_sq_queue(&unit[i].tag_set, + &ataflop_mq_ops, 2, + BLK_MQ_F_SHOULD_MERGE); + if (IS_ERR(unit[i].disk->queue)) { + ret = PTR_ERR(unit[i].disk->queue); + unit[i].disk->queue = NULL; + goto err; + } } if (UseTrackbuffer < 0) @@ -2035,7 +2002,8 @@ static int __init atari_floppy_init (void) DMABuffer = atari_stram_alloc(BUFFER_SIZE+512, "ataflop"); if (!DMABuffer) { printk(KERN_ERR "atari_floppy_init: cannot get dma buffer\n"); - goto Enomem; + ret = -ENOMEM; + goto err; } TrackBuffer = DMABuffer + 512; PhysDMABuffer = atari_stram_to_phys(DMABuffer); @@ -2063,7 +2031,8 @@ static int __init atari_floppy_init (void) config_types(); return 0; -Enomem: + +err: do { struct gendisk *disk = unit[i].disk; @@ -2072,12 +2041,13 @@ Enomem: blk_cleanup_queue(disk->queue); disk->queue = NULL; } + blk_mq_free_tag_set(&unit[i].tag_set); put_disk(unit[i].disk); } } while (i--); unregister_blkdev(FLOPPY_MAJOR, "fd"); - return -ENOMEM; + return ret; } #ifndef MODULE @@ -2124,11 +2094,10 @@ static void __exit atari_floppy_exit(void) int i; blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); for (i = 0; i < FD_MAX_UNITS; i++) { - struct request_queue *q = unit[i].disk->queue; - del_gendisk(unit[i].disk); + blk_cleanup_queue(unit[i].disk->queue); + blk_mq_free_tag_set(&unit[i].tag_set); put_disk(unit[i].disk); - blk_cleanup_queue(q); } unregister_blkdev(FLOPPY_MAJOR, "fd"); -- cgit v1.2.3 From a9f38e1dec107af70d81338332494bf0a1e76597 Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Mon, 15 Oct 2018 09:21:34 -0600 Subject: floppy: convert to blk-mq This driver likes to fetch requests from all over the place, so make queue_rq put requests on a list so that the logic stays the same. Tested with QEMU. Signed-off-by: Omar Sandoval Converted to blk_mq_init_sq_queue() and fixed a few spots where the tag_set leaked on cleanup. Signed-off-by: Jens Axboe --- drivers/block/floppy.c | 66 +++++++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 30 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index c494a771c06f..a8cfa011c284 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -252,13 +252,13 @@ static int allowed_drive_mask = 0x33; static int irqdma_allocated; -#include +#include #include #include /* for the compatibility eject ioctl */ #include +static LIST_HEAD(floppy_reqs); static struct request *current_req; -static void do_fd_request(struct request_queue *q); static int set_next_request(void); #ifndef fd_get_dma_residue @@ -414,10 +414,10 @@ static struct floppy_drive_struct drive_state[N_DRIVE]; static struct floppy_write_errors write_errors[N_DRIVE]; static struct timer_list motor_off_timer[N_DRIVE]; static struct gendisk *disks[N_DRIVE]; +static struct blk_mq_tag_set tag_sets[N_DRIVE]; static struct block_device *opened_bdev[N_DRIVE]; static DEFINE_MUTEX(open_lock); static struct floppy_raw_cmd *raw_cmd, default_raw_cmd; -static int fdc_queue; /* * This struct defines the different floppy types. @@ -2216,8 +2216,9 @@ static void floppy_end_request(struct request *req, blk_status_t error) /* current_count_sectors can be zero if transfer failed */ if (error) nr_sectors = blk_rq_cur_sectors(req); - if (__blk_end_request(req, error, nr_sectors << 9)) + if (blk_update_request(req, error, nr_sectors << 9)) return; + __blk_mq_end_request(req, error); /* We're done with the request */ floppy_off(drive); @@ -2797,27 +2798,14 @@ static int make_raw_rw_request(void) return 2; } -/* - * Round-robin between our available drives, doing one request from each - */ static int set_next_request(void) { - struct request_queue *q; - int old_pos = fdc_queue; - - do { - q = disks[fdc_queue]->queue; - if (++fdc_queue == N_DRIVE) - fdc_queue = 0; - if (q) { - current_req = blk_fetch_request(q); - if (current_req) { - current_req->error_count = 0; - break; - } - } - } while (fdc_queue != old_pos); - + current_req = list_first_entry_or_null(&floppy_reqs, struct request, + queuelist); + if (current_req) { + current_req->error_count = 0; + list_del_init(¤t_req->queuelist); + } return current_req != NULL; } @@ -2901,29 +2889,38 @@ static void process_fd_request(void) schedule_bh(redo_fd_request); } -static void do_fd_request(struct request_queue *q) +static blk_status_t floppy_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { + blk_mq_start_request(bd->rq); + if (WARN(max_buffer_sectors == 0, "VFS: %s called on non-open device\n", __func__)) - return; + return BLK_STS_IOERR; if (WARN(atomic_read(&usage_count) == 0, "warning: usage count=0, current_req=%p sect=%ld flags=%llx\n", current_req, (long)blk_rq_pos(current_req), (unsigned long long) current_req->cmd_flags)) - return; + return BLK_STS_IOERR; + + spin_lock_irq(&floppy_lock); + list_add_tail(&bd->rq->queuelist, &floppy_reqs); + spin_unlock_irq(&floppy_lock); if (test_and_set_bit(0, &fdc_busy)) { /* fdc busy, this new request will be treated when the current one is done */ is_alive(__func__, "old request running"); - return; + return BLK_STS_OK; } + command_status = FD_COMMAND_NONE; __reschedule_timeout(MAXTIMEOUT, "fd_request"); set_fdc(0); process_fd_request(); is_alive(__func__, ""); + return BLK_STS_OK; } static const struct cont_t poll_cont = { @@ -4486,6 +4483,10 @@ static struct platform_driver floppy_driver = { }, }; +static const struct blk_mq_ops floppy_mq_ops = { + .queue_rq = floppy_queue_rq, +}; + static struct platform_device floppy_device[N_DRIVE]; static bool floppy_available(int drive) @@ -4533,9 +4534,12 @@ static int __init do_floppy_init(void) goto out_put_disk; } - disks[drive]->queue = blk_init_queue(do_fd_request, &floppy_lock); - if (!disks[drive]->queue) { - err = -ENOMEM; + disks[drive]->queue = blk_mq_init_sq_queue(&tag_sets[drive], + &floppy_mq_ops, 2, + BLK_MQ_F_SHOULD_MERGE); + if (IS_ERR(disks[drive]->queue)) { + err = PTR_ERR(disks[drive]->queue); + disks[drive]->queue = NULL; goto out_put_disk; } @@ -4708,6 +4712,7 @@ out_put_disk: del_timer_sync(&motor_off_timer[drive]); blk_cleanup_queue(disks[drive]->queue); disks[drive]->queue = NULL; + blk_mq_free_tag_set(&tag_sets[drive]); } put_disk(disks[drive]); } @@ -4935,6 +4940,7 @@ static void __exit floppy_module_exit(void) platform_device_unregister(&floppy_device[drive]); } blk_cleanup_queue(disks[drive]->queue); + blk_mq_free_tag_set(&tag_sets[drive]); /* * These disks have not called add_disk(). Don't put down -- cgit v1.2.3 From 8535fd6f702a4b3e225258a86dcbf5dd93b73d51 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 15 Oct 2018 09:02:45 -0600 Subject: z2ram: convert to blk-mq Straight forward conversion to blk-mq, nothing special about this driver. Signed-off-by: Jens Axboe --- drivers/block/z2ram.c | 87 +++++++++++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 38 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index d0c5bc4e0703..1106c076fa4b 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include @@ -66,43 +66,44 @@ static DEFINE_SPINLOCK(z2ram_lock); static struct gendisk *z2ram_gendisk; -static void do_z2_request(struct request_queue *q) +static blk_status_t z2_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { - struct request *req; - - req = blk_fetch_request(q); - while (req) { - unsigned long start = blk_rq_pos(req) << 9; - unsigned long len = blk_rq_cur_bytes(req); - blk_status_t err = BLK_STS_OK; - - if (start + len > z2ram_size) { - pr_err(DEVICE_NAME ": bad access: block=%llu, " - "count=%u\n", - (unsigned long long)blk_rq_pos(req), - blk_rq_cur_sectors(req)); - err = BLK_STS_IOERR; - goto done; - } - while (len) { - unsigned long addr = start & Z2RAM_CHUNKMASK; - unsigned long size = Z2RAM_CHUNKSIZE - addr; - void *buffer = bio_data(req->bio); - - if (len < size) - size = len; - addr += z2ram_map[ start >> Z2RAM_CHUNKSHIFT ]; - if (rq_data_dir(req) == READ) - memcpy(buffer, (char *)addr, size); - else - memcpy((char *)addr, buffer, size); - start += size; - len -= size; - } - done: - if (!__blk_end_request_cur(req, err)) - req = blk_fetch_request(q); + struct request *req = bd->rq; + unsigned long start = blk_rq_pos(req) << 9; + unsigned long len = blk_rq_cur_bytes(req); + + blk_mq_start_request(req); + + if (start + len > z2ram_size) { + pr_err(DEVICE_NAME ": bad access: block=%llu, " + "count=%u\n", + (unsigned long long)blk_rq_pos(req), + blk_rq_cur_sectors(req)); + return BLK_STS_IOERR; + } + + spin_lock_irq(&z2ram_lock); + + while (len) { + unsigned long addr = start & Z2RAM_CHUNKMASK; + unsigned long size = Z2RAM_CHUNKSIZE - addr; + void *buffer = bio_data(req->bio); + + if (len < size) + size = len; + addr += z2ram_map[ start >> Z2RAM_CHUNKSHIFT ]; + if (rq_data_dir(req) == READ) + memcpy(buffer, (char *)addr, size); + else + memcpy((char *)addr, buffer, size); + start += size; + len -= size; } + + spin_unlock_irq(&z2ram_lock); + blk_mq_end_request(req, BLK_STS_OK); + return BLK_STS_OK; } static void @@ -337,6 +338,11 @@ static struct kobject *z2_find(dev_t dev, int *part, void *data) } static struct request_queue *z2_queue; +static struct blk_mq_tag_set tag_set; + +static const struct blk_mq_ops z2_mq_ops = { + .queue_rq = z2_queue_rq, +}; static int __init z2_init(void) @@ -355,9 +361,13 @@ z2_init(void) if (!z2ram_gendisk) goto out_disk; - z2_queue = blk_init_queue(do_z2_request, &z2ram_lock); - if (!z2_queue) + z2_queue = blk_mq_init_sq_queue(&tag_set, &z2_mq_ops, 16, + BLK_MQ_F_SHOULD_MERGE); + if (IS_ERR(z2_queue)) { + ret = PTR_ERR(z2_queue); + z2_queue = NULL; goto out_queue; + } z2ram_gendisk->major = Z2RAM_MAJOR; z2ram_gendisk->first_minor = 0; @@ -387,6 +397,7 @@ static void __exit z2_exit(void) del_gendisk(z2ram_gendisk); put_disk(z2ram_gendisk); blk_cleanup_queue(z2_queue); + blk_mq_free_tag_set(&tag_set); if ( current_device != -1 ) { -- cgit v1.2.3 From 0585b75437d335c6580066c1ab9ea3092139df32 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 15 Oct 2018 08:53:45 -0600 Subject: sx8: convert to blk-mq Convert from the old request_fn style driver to blk-mq. Signed-off-by: Jens Axboe --- drivers/block/sx8.c | 113 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 68 insertions(+), 45 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index 4d90e5eba2f5..16f37254bcf4 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include @@ -244,6 +244,7 @@ struct carm_port { unsigned int port_no; struct gendisk *disk; struct carm_host *host; + struct blk_mq_tag_set tag_set; /* attached device characteristics */ u64 capacity; @@ -279,6 +280,7 @@ struct carm_host { unsigned int state; u32 fw_ver; + struct blk_mq_tag_set tag_set; struct request_queue *oob_q; unsigned int n_oob; @@ -750,7 +752,7 @@ static inline void carm_end_request_queued(struct carm_host *host, struct request *req = crq->rq; int rc; - __blk_end_request_all(req, error); + blk_mq_end_request(req, error); rc = carm_put_request(host, crq); assert(rc == 0); @@ -760,7 +762,7 @@ static inline void carm_push_q (struct carm_host *host, struct request_queue *q) { unsigned int idx = host->wait_q_prod % CARM_MAX_WAIT_Q; - blk_stop_queue(q); + blk_mq_stop_hw_queues(q); VPRINTK("STOPPED QUEUE %p\n", q); host->wait_q[idx] = q; @@ -785,7 +787,7 @@ static inline void carm_round_robin(struct carm_host *host) { struct request_queue *q = carm_pop_q(host); if (q) { - blk_start_queue(q); + blk_mq_start_hw_queues(q); VPRINTK("STARTED QUEUE %p\n", q); } } @@ -802,62 +804,62 @@ static inline void carm_end_rq(struct carm_host *host, struct carm_request *crq, } } -static void carm_oob_rq_fn(struct request_queue *q) +static blk_status_t carm_oob_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { + struct request_queue *q = hctx->queue; struct carm_host *host = q->queuedata; struct carm_request *crq; - struct request *rq; int rc; - while (1) { - DPRINTK("get req\n"); - rq = blk_fetch_request(q); - if (!rq) - break; + blk_mq_start_request(bd->rq); - crq = rq->special; - assert(crq != NULL); - assert(crq->rq == rq); + spin_lock_irq(&host->lock); - crq->n_elem = 0; + crq = bd->rq->special; + assert(crq != NULL); + assert(crq->rq == bd->rq); - DPRINTK("send req\n"); - rc = carm_send_msg(host, crq); - if (rc) { - blk_requeue_request(q, rq); - carm_push_q(host, q); - return; /* call us again later, eventually */ - } + crq->n_elem = 0; + + DPRINTK("send req\n"); + rc = carm_send_msg(host, crq); + if (rc) { + carm_push_q(host, q); + spin_unlock_irq(&host->lock); + return BLK_STS_DEV_RESOURCE; } + + spin_unlock_irq(&host->lock); + return BLK_STS_OK; } -static void carm_rq_fn(struct request_queue *q) +static blk_status_t carm_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { + struct request_queue *q = hctx->queue; struct carm_port *port = q->queuedata; struct carm_host *host = port->host; struct carm_msg_rw *msg; struct carm_request *crq; - struct request *rq; + struct request *rq = bd->rq; struct scatterlist *sg; int writing = 0, pci_dir, i, n_elem, rc; u32 tmp; unsigned int msg_size; -queue_one_request: - VPRINTK("get req\n"); - rq = blk_peek_request(q); - if (!rq) - return; + blk_mq_start_request(rq); + + spin_lock_irq(&host->lock); crq = carm_get_request(host); if (!crq) { carm_push_q(host, q); - return; /* call us again later, eventually */ + spin_unlock_irq(&host->lock); + return BLK_STS_DEV_RESOURCE; } crq->rq = rq; - blk_start_request(rq); - if (rq_data_dir(rq) == WRITE) { writing = 1; pci_dir = PCI_DMA_TODEVICE; @@ -869,15 +871,19 @@ queue_one_request: sg = &crq->sg[0]; n_elem = blk_rq_map_sg(q, rq, sg); if (n_elem <= 0) { + /* request with no s/g entries? */ carm_end_rq(host, crq, BLK_STS_IOERR); - return; /* request with no s/g entries? */ + spin_unlock_irq(&host->lock); + return BLK_STS_IOERR; } /* map scatterlist to PCI bus addresses */ n_elem = pci_map_sg(host->pdev, sg, n_elem, pci_dir); if (n_elem <= 0) { + /* request with no s/g entries? */ carm_end_rq(host, crq, BLK_STS_IOERR); - return; /* request with no s/g entries? */ + spin_unlock_irq(&host->lock); + return BLK_STS_IOERR; } crq->n_elem = n_elem; crq->port = port; @@ -927,12 +933,13 @@ queue_one_request: rc = carm_send_msg(host, crq); if (rc) { carm_put_request(host, crq); - blk_requeue_request(q, rq); carm_push_q(host, q); - return; /* call us again later, eventually */ + spin_unlock_irq(&host->lock); + return BLK_STS_DEV_RESOURCE; } - goto queue_one_request; + spin_unlock_irq(&host->lock); + return BLK_STS_OK; } static void carm_handle_array_info(struct carm_host *host, @@ -1485,6 +1492,14 @@ static int carm_init_host(struct carm_host *host) return 0; } +static const struct blk_mq_ops carm_oob_mq_ops = { + .queue_rq = carm_oob_queue_rq, +}; + +static const struct blk_mq_ops carm_mq_ops = { + .queue_rq = carm_queue_rq, +}; + static int carm_init_disks(struct carm_host *host) { unsigned int i; @@ -1513,9 +1528,10 @@ static int carm_init_disks(struct carm_host *host) disk->fops = &carm_bd_ops; disk->private_data = port; - q = blk_init_queue(carm_rq_fn, &host->lock); - if (!q) { - rc = -ENOMEM; + q = blk_mq_init_sq_queue(&port->tag_set, &carm_mq_ops, + max_queue, BLK_MQ_F_SHOULD_MERGE); + if (IS_ERR(q)) { + rc = PTR_ERR(q); break; } disk->queue = q; @@ -1533,14 +1549,18 @@ static void carm_free_disks(struct carm_host *host) unsigned int i; for (i = 0; i < CARM_MAX_PORTS; i++) { - struct gendisk *disk = host->port[i].disk; + struct carm_port *port = &host->port[i]; + struct gendisk *disk = port->disk; + if (disk) { struct request_queue *q = disk->queue; if (disk->flags & GENHD_FL_UP) del_gendisk(disk); - if (q) + if (q) { + blk_mq_free_tag_set(&port->tag_set); blk_cleanup_queue(q); + } put_disk(disk); } } @@ -1636,11 +1656,12 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_iounmap; } - q = blk_init_queue(carm_oob_rq_fn, &host->lock); - if (!q) { + q = blk_mq_init_sq_queue(&host->tag_set, &carm_oob_mq_ops, 1, + BLK_MQ_F_NO_SCHED); + if (IS_ERR(q)) { printk(KERN_ERR DRV_NAME "(%s): OOB queue alloc failure\n", pci_name(pdev)); - rc = -ENOMEM; + rc = PTR_ERR(q); goto err_out_pci_free; } host->oob_q = q; @@ -1705,6 +1726,7 @@ err_out_free_majors: else if (host->major == 161) clear_bit(1, &carm_major_alloc); blk_cleanup_queue(host->oob_q); + blk_mq_free_tag_set(&host->tag_set); err_out_pci_free: pci_free_consistent(pdev, CARM_SHM_SIZE, host->shm, host->shm_dma); err_out_iounmap: @@ -1736,6 +1758,7 @@ static void carm_remove_one (struct pci_dev *pdev) else if (host->major == 161) clear_bit(1, &carm_major_alloc); blk_cleanup_queue(host->oob_q); + blk_mq_free_tag_set(&host->tag_set); pci_free_consistent(pdev, CARM_SHM_SIZE, host->shm, host->shm_dma); iounmap(host->mmio); kfree(host); -- cgit v1.2.3 From 6956b956934f10c19eca2a1d44f50a3bee860531 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 17 Oct 2018 17:25:13 +0200 Subject: drivers/block: Remove DAC960 driver The DAC960 driver has been obsoleted by the myrb/myrs drivers, so it can be dropped. Signed-off-by: Hannes Reinecke Reviewed-by: Christoph Hellwig Signed-off-by: Jens Axboe --- drivers/block/DAC960.c | 7229 ------------------------------------------------ drivers/block/DAC960.h | 4414 ----------------------------- drivers/block/Kconfig | 12 - drivers/block/Makefile | 1 - 4 files changed, 11656 deletions(-) delete mode 100644 drivers/block/DAC960.c delete mode 100644 drivers/block/DAC960.h (limited to 'drivers/block') diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c deleted file mode 100644 index 581312ac375f..000000000000 --- a/drivers/block/DAC960.c +++ /dev/null @@ -1,7229 +0,0 @@ -/* - - Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers - - Copyright 1998-2001 by Leonard N. Zubkoff - Portions Copyright 2002 by Mylex (An IBM Business Unit) - - This program is free software; you may redistribute and/or modify it under - the terms of the GNU General Public License Version 2 as published by the - Free Software Foundation. - - 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 complete details. - -*/ - - -#define DAC960_DriverVersion "2.5.49" -#define DAC960_DriverDate "21 Aug 2007" - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "DAC960.h" - -#define DAC960_GAM_MINOR 252 - - -static DEFINE_MUTEX(DAC960_mutex); -static DAC960_Controller_T *DAC960_Controllers[DAC960_MaxControllers]; -static int DAC960_ControllerCount; -static struct proc_dir_entry *DAC960_ProcDirectoryEntry; - -static long disk_size(DAC960_Controller_T *p, int drive_nr) -{ - if (p->FirmwareType == DAC960_V1_Controller) { - if (drive_nr >= p->LogicalDriveCount) - return 0; - return p->V1.LogicalDriveInformation[drive_nr]. - LogicalDriveSize; - } else { - DAC960_V2_LogicalDeviceInfo_T *i = - p->V2.LogicalDeviceInformation[drive_nr]; - if (i == NULL) - return 0; - return i->ConfigurableDeviceSize; - } -} - -static int DAC960_open(struct block_device *bdev, fmode_t mode) -{ - struct gendisk *disk = bdev->bd_disk; - DAC960_Controller_T *p = disk->queue->queuedata; - int drive_nr = (long)disk->private_data; - int ret = -ENXIO; - - mutex_lock(&DAC960_mutex); - if (p->FirmwareType == DAC960_V1_Controller) { - if (p->V1.LogicalDriveInformation[drive_nr]. - LogicalDriveState == DAC960_V1_LogicalDrive_Offline) - goto out; - } else { - DAC960_V2_LogicalDeviceInfo_T *i = - p->V2.LogicalDeviceInformation[drive_nr]; - if (!i || i->LogicalDeviceState == DAC960_V2_LogicalDevice_Offline) - goto out; - } - - check_disk_change(bdev); - - if (!get_capacity(p->disks[drive_nr])) - goto out; - ret = 0; -out: - mutex_unlock(&DAC960_mutex); - return ret; -} - -static int DAC960_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - struct gendisk *disk = bdev->bd_disk; - DAC960_Controller_T *p = disk->queue->queuedata; - int drive_nr = (long)disk->private_data; - - if (p->FirmwareType == DAC960_V1_Controller) { - geo->heads = p->V1.GeometryTranslationHeads; - geo->sectors = p->V1.GeometryTranslationSectors; - geo->cylinders = p->V1.LogicalDriveInformation[drive_nr]. - LogicalDriveSize / (geo->heads * geo->sectors); - } else { - DAC960_V2_LogicalDeviceInfo_T *i = - p->V2.LogicalDeviceInformation[drive_nr]; - switch (i->DriveGeometry) { - case DAC960_V2_Geometry_128_32: - geo->heads = 128; - geo->sectors = 32; - break; - case DAC960_V2_Geometry_255_63: - geo->heads = 255; - geo->sectors = 63; - break; - default: - DAC960_Error("Illegal Logical Device Geometry %d\n", - p, i->DriveGeometry); - return -EINVAL; - } - - geo->cylinders = i->ConfigurableDeviceSize / - (geo->heads * geo->sectors); - } - - return 0; -} - -static unsigned int DAC960_check_events(struct gendisk *disk, - unsigned int clearing) -{ - DAC960_Controller_T *p = disk->queue->queuedata; - int drive_nr = (long)disk->private_data; - - if (!p->LogicalDriveInitiallyAccessible[drive_nr]) - return DISK_EVENT_MEDIA_CHANGE; - return 0; -} - -static int DAC960_revalidate_disk(struct gendisk *disk) -{ - DAC960_Controller_T *p = disk->queue->queuedata; - int unit = (long)disk->private_data; - - set_capacity(disk, disk_size(p, unit)); - return 0; -} - -static const struct block_device_operations DAC960_BlockDeviceOperations = { - .owner = THIS_MODULE, - .open = DAC960_open, - .getgeo = DAC960_getgeo, - .check_events = DAC960_check_events, - .revalidate_disk = DAC960_revalidate_disk, -}; - - -/* - DAC960_AnnounceDriver announces the Driver Version and Date, Author's Name, - Copyright Notice, and Electronic Mail Address. -*/ - -static void DAC960_AnnounceDriver(DAC960_Controller_T *Controller) -{ - DAC960_Announce("***** DAC960 RAID Driver Version " - DAC960_DriverVersion " of " - DAC960_DriverDate " *****\n", Controller); - DAC960_Announce("Copyright 1998-2001 by Leonard N. Zubkoff " - "\n", Controller); -} - - -/* - DAC960_Failure prints a standardized error message, and then returns false. -*/ - -static bool DAC960_Failure(DAC960_Controller_T *Controller, - unsigned char *ErrorMessage) -{ - DAC960_Error("While configuring DAC960 PCI RAID Controller at\n", - Controller); - if (Controller->IO_Address == 0) - DAC960_Error("PCI Bus %d Device %d Function %d I/O Address N/A " - "PCI Address 0x%X\n", Controller, - Controller->Bus, Controller->Device, - Controller->Function, Controller->PCI_Address); - else DAC960_Error("PCI Bus %d Device %d Function %d I/O Address " - "0x%X PCI Address 0x%X\n", Controller, - Controller->Bus, Controller->Device, - Controller->Function, Controller->IO_Address, - Controller->PCI_Address); - DAC960_Error("%s FAILED - DETACHING\n", Controller, ErrorMessage); - return false; -} - -/* - init_dma_loaf() and slice_dma_loaf() are helper functions for - aggregating the dma-mapped memory for a well-known collection of - data structures that are of different lengths. - - These routines don't guarantee any alignment. The caller must - include any space needed for alignment in the sizes of the structures - that are passed in. - */ - -static bool init_dma_loaf(struct pci_dev *dev, struct dma_loaf *loaf, - size_t len) -{ - void *cpu_addr; - dma_addr_t dma_handle; - - cpu_addr = pci_alloc_consistent(dev, len, &dma_handle); - if (cpu_addr == NULL) - return false; - - loaf->cpu_free = loaf->cpu_base = cpu_addr; - loaf->dma_free =loaf->dma_base = dma_handle; - loaf->length = len; - memset(cpu_addr, 0, len); - return true; -} - -static void *slice_dma_loaf(struct dma_loaf *loaf, size_t len, - dma_addr_t *dma_handle) -{ - void *cpu_end = loaf->cpu_free + len; - void *cpu_addr = loaf->cpu_free; - - BUG_ON(cpu_end > loaf->cpu_base + loaf->length); - *dma_handle = loaf->dma_free; - loaf->cpu_free = cpu_end; - loaf->dma_free += len; - return cpu_addr; -} - -static void free_dma_loaf(struct pci_dev *dev, struct dma_loaf *loaf_handle) -{ - if (loaf_handle->cpu_base != NULL) - pci_free_consistent(dev, loaf_handle->length, - loaf_handle->cpu_base, loaf_handle->dma_base); -} - - -/* - DAC960_CreateAuxiliaryStructures allocates and initializes the auxiliary - data structures for Controller. It returns true on success and false on - failure. -*/ - -static bool DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller) -{ - int CommandAllocationLength, CommandAllocationGroupSize; - int CommandsRemaining = 0, CommandIdentifier, CommandGroupByteCount; - void *AllocationPointer = NULL; - void *ScatterGatherCPU = NULL; - dma_addr_t ScatterGatherDMA; - struct dma_pool *ScatterGatherPool; - void *RequestSenseCPU = NULL; - dma_addr_t RequestSenseDMA; - struct dma_pool *RequestSensePool = NULL; - - if (Controller->FirmwareType == DAC960_V1_Controller) - { - CommandAllocationLength = offsetof(DAC960_Command_T, V1.EndMarker); - CommandAllocationGroupSize = DAC960_V1_CommandAllocationGroupSize; - ScatterGatherPool = dma_pool_create("DAC960_V1_ScatterGather", - &Controller->PCIDevice->dev, - DAC960_V1_ScatterGatherLimit * sizeof(DAC960_V1_ScatterGatherSegment_T), - sizeof(DAC960_V1_ScatterGatherSegment_T), 0); - if (ScatterGatherPool == NULL) - return DAC960_Failure(Controller, - "AUXILIARY STRUCTURE CREATION (SG)"); - Controller->ScatterGatherPool = ScatterGatherPool; - } - else - { - CommandAllocationLength = offsetof(DAC960_Command_T, V2.EndMarker); - CommandAllocationGroupSize = DAC960_V2_CommandAllocationGroupSize; - ScatterGatherPool = dma_pool_create("DAC960_V2_ScatterGather", - &Controller->PCIDevice->dev, - DAC960_V2_ScatterGatherLimit * sizeof(DAC960_V2_ScatterGatherSegment_T), - sizeof(DAC960_V2_ScatterGatherSegment_T), 0); - if (ScatterGatherPool == NULL) - return DAC960_Failure(Controller, - "AUXILIARY STRUCTURE CREATION (SG)"); - RequestSensePool = dma_pool_create("DAC960_V2_RequestSense", - &Controller->PCIDevice->dev, sizeof(DAC960_SCSI_RequestSense_T), - sizeof(int), 0); - if (RequestSensePool == NULL) { - dma_pool_destroy(ScatterGatherPool); - return DAC960_Failure(Controller, - "AUXILIARY STRUCTURE CREATION (SG)"); - } - Controller->ScatterGatherPool = ScatterGatherPool; - Controller->V2.RequestSensePool = RequestSensePool; - } - Controller->CommandAllocationGroupSize = CommandAllocationGroupSize; - Controller->FreeCommands = NULL; - for (CommandIdentifier = 1; - CommandIdentifier <= Controller->DriverQueueDepth; - CommandIdentifier++) - { - DAC960_Command_T *Command; - if (--CommandsRemaining <= 0) - { - CommandsRemaining = - Controller->DriverQueueDepth - CommandIdentifier + 1; - if (CommandsRemaining > CommandAllocationGroupSize) - CommandsRemaining = CommandAllocationGroupSize; - CommandGroupByteCount = - CommandsRemaining * CommandAllocationLength; - AllocationPointer = kzalloc(CommandGroupByteCount, GFP_ATOMIC); - if (AllocationPointer == NULL) - return DAC960_Failure(Controller, - "AUXILIARY STRUCTURE CREATION"); - } - Command = (DAC960_Command_T *) AllocationPointer; - AllocationPointer += CommandAllocationLength; - Command->CommandIdentifier = CommandIdentifier; - Command->Controller = Controller; - Command->Next = Controller->FreeCommands; - Controller->FreeCommands = Command; - Controller->Commands[CommandIdentifier-1] = Command; - ScatterGatherCPU = dma_pool_alloc(ScatterGatherPool, GFP_ATOMIC, - &ScatterGatherDMA); - if (ScatterGatherCPU == NULL) - return DAC960_Failure(Controller, "AUXILIARY STRUCTURE CREATION"); - - if (RequestSensePool != NULL) { - RequestSenseCPU = dma_pool_alloc(RequestSensePool, GFP_ATOMIC, - &RequestSenseDMA); - if (RequestSenseCPU == NULL) { - dma_pool_free(ScatterGatherPool, ScatterGatherCPU, - ScatterGatherDMA); - return DAC960_Failure(Controller, - "AUXILIARY STRUCTURE CREATION"); - } - } - if (Controller->FirmwareType == DAC960_V1_Controller) { - Command->cmd_sglist = Command->V1.ScatterList; - Command->V1.ScatterGatherList = - (DAC960_V1_ScatterGatherSegment_T *)ScatterGatherCPU; - Command->V1.ScatterGatherListDMA = ScatterGatherDMA; - sg_init_table(Command->cmd_sglist, DAC960_V1_ScatterGatherLimit); - } else { - Command->cmd_sglist = Command->V2.ScatterList; - Command->V2.ScatterGatherList = - (DAC960_V2_ScatterGatherSegment_T *)ScatterGatherCPU; - Command->V2.ScatterGatherListDMA = ScatterGatherDMA; - Command->V2.RequestSense = - (DAC960_SCSI_RequestSense_T *)RequestSenseCPU; - Command->V2.RequestSenseDMA = RequestSenseDMA; - sg_init_table(Command->cmd_sglist, DAC960_V2_ScatterGatherLimit); - } - } - return true; -} - - -/* - DAC960_DestroyAuxiliaryStructures deallocates the auxiliary data - structures for Controller. -*/ - -static void DAC960_DestroyAuxiliaryStructures(DAC960_Controller_T *Controller) -{ - int i; - struct dma_pool *ScatterGatherPool = Controller->ScatterGatherPool; - struct dma_pool *RequestSensePool = NULL; - void *ScatterGatherCPU; - dma_addr_t ScatterGatherDMA; - void *RequestSenseCPU; - dma_addr_t RequestSenseDMA; - DAC960_Command_T *CommandGroup = NULL; - - - if (Controller->FirmwareType == DAC960_V2_Controller) - RequestSensePool = Controller->V2.RequestSensePool; - - Controller->FreeCommands = NULL; - for (i = 0; i < Controller->DriverQueueDepth; i++) - { - DAC960_Command_T *Command = Controller->Commands[i]; - - if (Command == NULL) - continue; - - if (Controller->FirmwareType == DAC960_V1_Controller) { - ScatterGatherCPU = (void *)Command->V1.ScatterGatherList; - ScatterGatherDMA = Command->V1.ScatterGatherListDMA; - RequestSenseCPU = NULL; - RequestSenseDMA = (dma_addr_t)0; - } else { - ScatterGatherCPU = (void *)Command->V2.ScatterGatherList; - ScatterGatherDMA = Command->V2.ScatterGatherListDMA; - RequestSenseCPU = (void *)Command->V2.RequestSense; - RequestSenseDMA = Command->V2.RequestSenseDMA; - } - if (ScatterGatherCPU != NULL) - dma_pool_free(ScatterGatherPool, ScatterGatherCPU, ScatterGatherDMA); - if (RequestSenseCPU != NULL) - dma_pool_free(RequestSensePool, RequestSenseCPU, RequestSenseDMA); - - if ((Command->CommandIdentifier - % Controller->CommandAllocationGroupSize) == 1) { - /* - * We can't free the group of commands until all of the - * request sense and scatter gather dma structures are free. - * Remember the beginning of the group, but don't free it - * until we've reached the beginning of the next group. - */ - kfree(CommandGroup); - CommandGroup = Command; - } - Controller->Commands[i] = NULL; - } - kfree(CommandGroup); - - if (Controller->CombinedStatusBuffer != NULL) - { - kfree(Controller->CombinedStatusBuffer); - Controller->CombinedStatusBuffer = NULL; - Controller->CurrentStatusBuffer = NULL; - } - - dma_pool_destroy(ScatterGatherPool); - if (Controller->FirmwareType == DAC960_V1_Controller) - return; - - dma_pool_destroy(RequestSensePool); - - for (i = 0; i < DAC960_MaxLogicalDrives; i++) { - kfree(Controller->V2.LogicalDeviceInformation[i]); - Controller->V2.LogicalDeviceInformation[i] = NULL; - } - - for (i = 0; i < DAC960_V2_MaxPhysicalDevices; i++) - { - kfree(Controller->V2.PhysicalDeviceInformation[i]); - Controller->V2.PhysicalDeviceInformation[i] = NULL; - kfree(Controller->V2.InquiryUnitSerialNumber[i]); - Controller->V2.InquiryUnitSerialNumber[i] = NULL; - } -} - - -/* - DAC960_V1_ClearCommand clears critical fields of Command for DAC960 V1 - Firmware Controllers. -*/ - -static inline void DAC960_V1_ClearCommand(DAC960_Command_T *Command) -{ - DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox; - memset(CommandMailbox, 0, sizeof(DAC960_V1_CommandMailbox_T)); - Command->V1.CommandStatus = 0; -} - - -/* - DAC960_V2_ClearCommand clears critical fields of Command for DAC960 V2 - Firmware Controllers. -*/ - -static inline void DAC960_V2_ClearCommand(DAC960_Command_T *Command) -{ - DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; - memset(CommandMailbox, 0, sizeof(DAC960_V2_CommandMailbox_T)); - Command->V2.CommandStatus = 0; -} - - -/* - DAC960_AllocateCommand allocates a Command structure from Controller's - free list. During driver initialization, a special initialization command - has been placed on the free list to guarantee that command allocation can - never fail. -*/ - -static inline DAC960_Command_T *DAC960_AllocateCommand(DAC960_Controller_T - *Controller) -{ - DAC960_Command_T *Command = Controller->FreeCommands; - if (Command == NULL) return NULL; - Controller->FreeCommands = Command->Next; - Command->Next = NULL; - return Command; -} - - -/* - DAC960_DeallocateCommand deallocates Command, returning it to Controller's - free list. -*/ - -static inline void DAC960_DeallocateCommand(DAC960_Command_T *Command) -{ - DAC960_Controller_T *Controller = Command->Controller; - - Command->Request = NULL; - Command->Next = Controller->FreeCommands; - Controller->FreeCommands = Command; -} - - -/* - DAC960_WaitForCommand waits for a wake_up on Controller's Command Wait Queue. -*/ - -static void DAC960_WaitForCommand(DAC960_Controller_T *Controller) -{ - spin_unlock_irq(&Controller->queue_lock); - __wait_event(Controller->CommandWaitQueue, Controller->FreeCommands); - spin_lock_irq(&Controller->queue_lock); -} - -/* - DAC960_GEM_QueueCommand queues Command for DAC960 GEM Series Controllers. -*/ - -static void DAC960_GEM_QueueCommand(DAC960_Command_T *Command) -{ - DAC960_Controller_T *Controller = Command->Controller; - void __iomem *ControllerBaseAddress = Controller->BaseAddress; - DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; - DAC960_V2_CommandMailbox_T *NextCommandMailbox = - Controller->V2.NextCommandMailbox; - - CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier; - DAC960_GEM_WriteCommandMailbox(NextCommandMailbox, CommandMailbox); - - if (Controller->V2.PreviousCommandMailbox1->Words[0] == 0 || - Controller->V2.PreviousCommandMailbox2->Words[0] == 0) - DAC960_GEM_MemoryMailboxNewCommand(ControllerBaseAddress); - - Controller->V2.PreviousCommandMailbox2 = - Controller->V2.PreviousCommandMailbox1; - Controller->V2.PreviousCommandMailbox1 = NextCommandMailbox; - - if (++NextCommandMailbox > Controller->V2.LastCommandMailbox) - NextCommandMailbox = Controller->V2.FirstCommandMailbox; - - Controller->V2.NextCommandMailbox = NextCommandMailbox; -} - -/* - DAC960_BA_QueueCommand queues Command for DAC960 BA Series Controllers. -*/ - -static void DAC960_BA_QueueCommand(DAC960_Command_T *Command) -{ - DAC960_Controller_T *Controller = Command->Controller; - void __iomem *ControllerBaseAddress = Controller->BaseAddress; - DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; - DAC960_V2_CommandMailbox_T *NextCommandMailbox = - Controller->V2.NextCommandMailbox; - CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier; - DAC960_BA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox); - if (Controller->V2.PreviousCommandMailbox1->Words[0] == 0 || - Controller->V2.PreviousCommandMailbox2->Words[0] == 0) - DAC960_BA_MemoryMailboxNewCommand(ControllerBaseAddress); - Controller->V2.PreviousCommandMailbox2 = - Controller->V2.PreviousCommandMailbox1; - Controller->V2.PreviousCommandMailbox1 = NextCommandMailbox; - if (++NextCommandMailbox > Controller->V2.LastCommandMailbox) - NextCommandMailbox = Controller->V2.FirstCommandMailbox; - Controller->V2.NextCommandMailbox = NextCommandMailbox; -} - - -/* - DAC960_LP_QueueCommand queues Command for DAC960 LP Series Controllers. -*/ - -static void DAC960_LP_QueueCommand(DAC960_Command_T *Command) -{ - DAC960_Controller_T *Controller = Command->Controller; - void __iomem *ControllerBaseAddress = Controller->BaseAddress; - DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; - DAC960_V2_CommandMailbox_T *NextCommandMailbox = - Controller->V2.NextCommandMailbox; - CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier; - DAC960_LP_WriteCommandMailbox(NextCommandMailbox, CommandMailbox); - if (Controller->V2.PreviousCommandMailbox1->Words[0] == 0 || - Controller->V2.PreviousCommandMailbox2->Words[0] == 0) - DAC960_LP_MemoryMailboxNewCommand(ControllerBaseAddress); - Controller->V2.PreviousCommandMailbox2 = - Controller->V2.PreviousCommandMailbox1; - Controller->V2.PreviousCommandMailbox1 = NextCommandMailbox; - if (++NextCommandMailbox > Controller->V2.LastCommandMailbox) - NextCommandMailbox = Controller->V2.FirstCommandMailbox; - Controller->V2.NextCommandMailbox = NextCommandMailbox; -} - - -/* - DAC960_LA_QueueCommandDualMode queues Command for DAC960 LA Series - Controllers with Dual Mode Firmware. -*/ - -static void DAC960_LA_QueueCommandDualMode(DAC960_Command_T *Command) -{ - DAC960_Controller_T *Controller = Command->Controller; - void __iomem *ControllerBaseAddress = Controller->BaseAddress; - DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox; - DAC960_V1_CommandMailbox_T *NextCommandMailbox = - Controller->V1.NextCommandMailbox; - CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier; - DAC960_LA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox); - if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 || - Controller->V1.PreviousCommandMailbox2->Words[0] == 0) - DAC960_LA_MemoryMailboxNewCommand(ControllerBaseAddress); - Controller->V1.PreviousCommandMailbox2 = - Controller->V1.PreviousCommandMailbox1; - Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox; - if (++NextCommandMailbox > Controller->V1.LastCommandMailbox) - NextCommandMailbox = Controller->V1.FirstCommandMailbox; - Controller->V1.NextCommandMailbox = NextCommandMailbox; -} - - -/* - DAC960_LA_QueueCommandSingleMode queues Command for DAC960 LA Series - Controllers with Single Mode Firmware. -*/ - -static void DAC960_LA_QueueCommandSingleMode(DAC960_Command_T *Command) -{ - DAC960_Controller_T *Controller = Command->Controller; - void __iomem *ControllerBaseAddress = Controller->BaseAddress; - DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox; - DAC960_V1_CommandMailbox_T *NextCommandMailbox = - Controller->V1.NextCommandMailbox; - CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier; - DAC960_LA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox); - if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 || - Controller->V1.PreviousCommandMailbox2->Words[0] == 0) - DAC960_LA_HardwareMailboxNewCommand(ControllerBaseAddress); - Controller->V1.PreviousCommandMailbox2 = - Controller->V1.PreviousCommandMailbox1; - Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox; - if (++NextCommandMailbox > Controller->V1.LastCommandMailbox) - NextCommandMailbox = Controller->V1.FirstCommandMailbox; - Controller->V1.NextCommandMailbox = NextCommandMailbox; -} - - -/* - DAC960_PG_QueueCommandDualMode queues Command for DAC960 PG Series - Controllers with Dual Mode Firmware. -*/ - -static void DAC960_PG_QueueCommandDualMode(DAC960_Command_T *Command) -{ - DAC960_Controller_T *Controller = Command->Controller; - void __iomem *ControllerBaseAddress = Controller->BaseAddress; - DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox; - DAC960_V1_CommandMailbox_T *NextCommandMailbox = - Controller->V1.NextCommandMailbox; - CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier; - DAC960_PG_WriteCommandMailbox(NextCommandMailbox, CommandMailbox); - if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 || - Controller->V1.PreviousCommandMailbox2->Words[0] == 0) - DAC960_PG_MemoryMailboxNewCommand(ControllerBaseAddress); - Controller->V1.PreviousCommandMailbox2 = - Controller->V1.PreviousCommandMailbox1; - Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox; - if (++NextCommandMailbox > Controller->V1.LastCommandMailbox) - NextCommandMailbox = Controller->V1.FirstCommandMailbox; - Controller->V1.NextCommandMailbox = NextCommandMailbox; -} - - -/* - DAC960_PG_QueueCommandSingleMode queues Command for DAC960 PG Series - Controllers with Single Mode Firmware. -*/ - -static void DAC960_PG_QueueCommandSingleMode(DAC960_Command_T *Command) -{ - DAC960_Controller_T *Controller = Command->Controller; - void __iomem *ControllerBaseAddress = Controller->BaseAddress; - DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox; - DAC960_V1_CommandMailbox_T *NextCommandMailbox = - Controller->V1.NextCommandMailbox; - CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier; - DAC960_PG_WriteCommandMailbox(NextCommandMailbox, CommandMailbox); - if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 || - Controller->V1.PreviousCommandMailbox2->Words[0] == 0) - DAC960_PG_HardwareMailboxNewCommand(ControllerBaseAddress); - Controller->V1.PreviousCommandMailbox2 = - Controller->V1.PreviousCommandMailbox1; - Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox; - if (++NextCommandMailbox > Controller->V1.LastCommandMailbox) - NextCommandMailbox = Controller->V1.FirstCommandMailbox; - Controller->V1.NextCommandMailbox = NextCommandMailbox; -} - - -/* - DAC960_PD_QueueCommand queues Command for DAC960 PD Series Controllers. -*/ - -static void DAC960_PD_QueueCommand(DAC960_Command_T *Command) -{ - DAC960_Controller_T *Controller = Command->Controller; - void __iomem *ControllerBaseAddress = Controller->BaseAddress; - DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox; - CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier; - while (DAC960_PD_MailboxFullP(ControllerBaseAddress)) - udelay(1); - DAC960_PD_WriteCommandMailbox(ControllerBaseAddress, CommandMailbox); - DAC960_PD_NewCommand(ControllerBaseAddress); -} - - -/* - DAC960_P_QueueCommand queues Command for DAC960 P Series Controllers. -*/ - -static void DAC960_P_QueueCommand(DAC960_Command_T *Command) -{ - DAC960_Controller_T *Controller = Command->Controller; - void __iomem *ControllerBaseAddress = Controller->BaseAddress; - DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox; - CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier; - switch (CommandMailbox->Common.CommandOpcode) - { - case DAC960_V1_Enquiry: - CommandMailbox->Common.CommandOpcode = DAC960_V1_Enquiry_Old; - break; - case DAC960_V1_GetDeviceState: - CommandMailbox->Common.CommandOpcode = DAC960_V1_GetDeviceState_Old; - break; - case DAC960_V1_Read: - CommandMailbox->Common.CommandOpcode = DAC960_V1_Read_Old; - DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox); - break; - case DAC960_V1_Write: - CommandMailbox->Common.CommandOpcode = DAC960_V1_Write_Old; - DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox); - break; - case DAC960_V1_ReadWithScatterGather: - CommandMailbox->Common.CommandOpcode = - DAC960_V1_ReadWithScatterGather_Old; - DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox); - break; - case DAC960_V1_WriteWithScatterGather: - CommandMailbox->Common.CommandOpcode = - DAC960_V1_WriteWithScatterGather_Old; - DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox); - break; - default: - break; - } - while (DAC960_PD_MailboxFullP(ControllerBaseAddress)) - udelay(1); - DAC960_PD_WriteCommandMailbox(ControllerBaseAddress, CommandMailbox); - DAC960_PD_NewCommand(ControllerBaseAddress); -} - - -/* - DAC960_ExecuteCommand executes Command and waits for completion. -*/ - -static void DAC960_ExecuteCommand(DAC960_Command_T *Command) -{ - DAC960_Controller_T *Controller = Command->Controller; - DECLARE_COMPLETION_ONSTACK(Completion); - unsigned long flags; - Command->Completion = &Completion; - - spin_lock_irqsave(&Controller->queue_lock, flags); - DAC960_QueueCommand(Command); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - - if (in_interrupt()) - return; - wait_for_completion(&Completion); -} - - -/* - DAC960_V1_ExecuteType3 executes a DAC960 V1 Firmware Controller Type 3 - Command and waits for completion. It returns true on success and false - on failure. -*/ - -static bool DAC960_V1_ExecuteType3(DAC960_Controller_T *Controller, - DAC960_V1_CommandOpcode_T CommandOpcode, - dma_addr_t DataDMA) -{ - DAC960_Command_T *Command = DAC960_AllocateCommand(Controller); - DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox; - DAC960_V1_CommandStatus_T CommandStatus; - DAC960_V1_ClearCommand(Command); - Command->CommandType = DAC960_ImmediateCommand; - CommandMailbox->Type3.CommandOpcode = CommandOpcode; - CommandMailbox->Type3.BusAddress = DataDMA; - DAC960_ExecuteCommand(Command); - CommandStatus = Command->V1.CommandStatus; - DAC960_DeallocateCommand(Command); - return (CommandStatus == DAC960_V1_NormalCompletion); -} - - -/* - DAC960_V1_ExecuteTypeB executes a DAC960 V1 Firmware Controller Type 3B - Command and waits for completion. It returns true on success and false - on failure. -*/ - -static bool DAC960_V1_ExecuteType3B(DAC960_Controller_T *Controller, - DAC960_V1_CommandOpcode_T CommandOpcode, - unsigned char CommandOpcode2, - dma_addr_t DataDMA) -{ - DAC960_Command_T *Command = DAC960_AllocateCommand(Controller); - DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox; - DAC960_V1_CommandStatus_T CommandStatus; - DAC960_V1_ClearCommand(Command); - Command->CommandType = DAC960_ImmediateCommand; - CommandMailbox->Type3B.CommandOpcode = CommandOpcode; - CommandMailbox->Type3B.CommandOpcode2 = CommandOpcode2; - CommandMailbox->Type3B.BusAddress = DataDMA; - DAC960_ExecuteCommand(Command); - CommandStatus = Command->V1.CommandStatus; - DAC960_DeallocateCommand(Command); - return (CommandStatus == DAC960_V1_NormalCompletion); -} - - -/* - DAC960_V1_ExecuteType3D executes a DAC960 V1 Firmware Controller Type 3D - Command and waits for completion. It returns true on success and false - on failure. -*/ - -static bool DAC960_V1_ExecuteType3D(DAC960_Controller_T *Controller, - DAC960_V1_CommandOpcode_T CommandOpcode, - unsigned char Channel, - unsigned char TargetID, - dma_addr_t DataDMA) -{ - DAC960_Command_T *Command = DAC960_AllocateCommand(Controller); - DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox; - DAC960_V1_CommandStatus_T CommandStatus; - DAC960_V1_ClearCommand(Command); - Command->CommandType = DAC960_ImmediateCommand; - CommandMailbox->Type3D.CommandOpcode = CommandOpcode; - CommandMailbox->Type3D.Channel = Channel; - CommandMailbox->Type3D.TargetID = TargetID; - CommandMailbox->Type3D.BusAddress = DataDMA; - DAC960_ExecuteCommand(Command); - CommandStatus = Command->V1.CommandStatus; - DAC960_DeallocateCommand(Command); - return (CommandStatus == DAC960_V1_NormalCompletion); -} - - -/* - DAC960_V2_GeneralInfo executes a DAC960 V2 Firmware General Information - Reading IOCTL Command and waits for completion. It returns true on success - and false on failure. - - Return data in The controller's HealthStatusBuffer, which is dma-able memory -*/ - -static bool DAC960_V2_GeneralInfo(DAC960_Controller_T *Controller) -{ - DAC960_Command_T *Command = DAC960_AllocateCommand(Controller); - DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; - DAC960_V2_CommandStatus_T CommandStatus; - DAC960_V2_ClearCommand(Command); - Command->CommandType = DAC960_ImmediateCommand; - CommandMailbox->Common.CommandOpcode = DAC960_V2_IOCTL; - CommandMailbox->Common.CommandControlBits - .DataTransferControllerToHost = true; - CommandMailbox->Common.CommandControlBits - .NoAutoRequestSense = true; - CommandMailbox->Common.DataTransferSize = sizeof(DAC960_V2_HealthStatusBuffer_T); - CommandMailbox->Common.IOCTL_Opcode = DAC960_V2_GetHealthStatus; - CommandMailbox->Common.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentDataPointer = - Controller->V2.HealthStatusBufferDMA; - CommandMailbox->Common.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentByteCount = - CommandMailbox->Common.DataTransferSize; - DAC960_ExecuteCommand(Command); - CommandStatus = Command->V2.CommandStatus; - DAC960_DeallocateCommand(Command); - return (CommandStatus == DAC960_V2_NormalCompletion); -} - - -/* - DAC960_V2_ControllerInfo executes a DAC960 V2 Firmware Controller - Information Reading IOCTL Command and waits for completion. It returns - true on success and false on failure. - - Data is returned in the controller's V2.NewControllerInformation dma-able - memory buffer. -*/ - -static bool DAC960_V2_NewControllerInfo(DAC960_Controller_T *Controller) -{ - DAC960_Command_T *Command = DAC960_AllocateCommand(Controller); - DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; - DAC960_V2_CommandStatus_T CommandStatus; - DAC960_V2_ClearCommand(Command); - Command->CommandType = DAC960_ImmediateCommand; - CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL; - CommandMailbox->ControllerInfo.CommandControlBits - .DataTransferControllerToHost = true; - CommandMailbox->ControllerInfo.CommandControlBits - .NoAutoRequestSense = true; - CommandMailbox->ControllerInfo.DataTransferSize = sizeof(DAC960_V2_ControllerInfo_T); - CommandMailbox->ControllerInfo.ControllerNumber = 0; - CommandMailbox->ControllerInfo.IOCTL_Opcode = DAC960_V2_GetControllerInfo; - CommandMailbox->ControllerInfo.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentDataPointer = - Controller->V2.NewControllerInformationDMA; - CommandMailbox->ControllerInfo.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentByteCount = - CommandMailbox->ControllerInfo.DataTransferSize; - DAC960_ExecuteCommand(Command); - CommandStatus = Command->V2.CommandStatus; - DAC960_DeallocateCommand(Command); - return (CommandStatus == DAC960_V2_NormalCompletion); -} - - -/* - DAC960_V2_LogicalDeviceInfo executes a DAC960 V2 Firmware Controller Logical - Device Information Reading IOCTL Command and waits for completion. It - returns true on success and false on failure. - - Data is returned in the controller's V2.NewLogicalDeviceInformation -*/ - -static bool DAC960_V2_NewLogicalDeviceInfo(DAC960_Controller_T *Controller, - unsigned short LogicalDeviceNumber) -{ - DAC960_Command_T *Command = DAC960_AllocateCommand(Controller); - DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; - DAC960_V2_CommandStatus_T CommandStatus; - - DAC960_V2_ClearCommand(Command); - Command->CommandType = DAC960_ImmediateCommand; - CommandMailbox->LogicalDeviceInfo.CommandOpcode = - DAC960_V2_IOCTL; - CommandMailbox->LogicalDeviceInfo.CommandControlBits - .DataTransferControllerToHost = true; - CommandMailbox->LogicalDeviceInfo.CommandControlBits - .NoAutoRequestSense = true; - CommandMailbox->LogicalDeviceInfo.DataTransferSize = - sizeof(DAC960_V2_LogicalDeviceInfo_T); - CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber = - LogicalDeviceNumber; - CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode = DAC960_V2_GetLogicalDeviceInfoValid; - CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentDataPointer = - Controller->V2.NewLogicalDeviceInformationDMA; - CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentByteCount = - CommandMailbox->LogicalDeviceInfo.DataTransferSize; - DAC960_ExecuteCommand(Command); - CommandStatus = Command->V2.CommandStatus; - DAC960_DeallocateCommand(Command); - return (CommandStatus == DAC960_V2_NormalCompletion); -} - - -/* - DAC960_V2_PhysicalDeviceInfo executes a DAC960 V2 Firmware Controller "Read - Physical Device Information" IOCTL Command and waits for completion. It - returns true on success and false on failure. - - The Channel, TargetID, LogicalUnit arguments should be 0 the first time - this function is called for a given controller. This will return data - for the "first" device on that controller. The returned data includes a - Channel, TargetID, LogicalUnit that can be passed in to this routine to - get data for the NEXT device on that controller. - - Data is stored in the controller's V2.NewPhysicalDeviceInfo dma-able - memory buffer. - -*/ - -static bool DAC960_V2_NewPhysicalDeviceInfo(DAC960_Controller_T *Controller, - unsigned char Channel, - unsigned char TargetID, - unsigned char LogicalUnit) -{ - DAC960_Command_T *Command = DAC960_AllocateCommand(Controller); - DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; - DAC960_V2_CommandStatus_T CommandStatus; - - DAC960_V2_ClearCommand(Command); - Command->CommandType = DAC960_ImmediateCommand; - CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL; - CommandMailbox->PhysicalDeviceInfo.CommandControlBits - .DataTransferControllerToHost = true; - CommandMailbox->PhysicalDeviceInfo.CommandControlBits - .NoAutoRequestSense = true; - CommandMailbox->PhysicalDeviceInfo.DataTransferSize = - sizeof(DAC960_V2_PhysicalDeviceInfo_T); - CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.LogicalUnit = LogicalUnit; - CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID = TargetID; - CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel = Channel; - CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode = - DAC960_V2_GetPhysicalDeviceInfoValid; - CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentDataPointer = - Controller->V2.NewPhysicalDeviceInformationDMA; - CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentByteCount = - CommandMailbox->PhysicalDeviceInfo.DataTransferSize; - DAC960_ExecuteCommand(Command); - CommandStatus = Command->V2.CommandStatus; - DAC960_DeallocateCommand(Command); - return (CommandStatus == DAC960_V2_NormalCompletion); -} - - -static void DAC960_V2_ConstructNewUnitSerialNumber( - DAC960_Controller_T *Controller, - DAC960_V2_CommandMailbox_T *CommandMailbox, int Channel, int TargetID, - int LogicalUnit) -{ - CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10_Passthru; - CommandMailbox->SCSI_10.CommandControlBits - .DataTransferControllerToHost = true; - CommandMailbox->SCSI_10.CommandControlBits - .NoAutoRequestSense = true; - CommandMailbox->SCSI_10.DataTransferSize = - sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T); - CommandMailbox->SCSI_10.PhysicalDevice.LogicalUnit = LogicalUnit; - CommandMailbox->SCSI_10.PhysicalDevice.TargetID = TargetID; - CommandMailbox->SCSI_10.PhysicalDevice.Channel = Channel; - CommandMailbox->SCSI_10.CDBLength = 6; - CommandMailbox->SCSI_10.SCSI_CDB[0] = 0x12; /* INQUIRY */ - CommandMailbox->SCSI_10.SCSI_CDB[1] = 1; /* EVPD = 1 */ - CommandMailbox->SCSI_10.SCSI_CDB[2] = 0x80; /* Page Code */ - CommandMailbox->SCSI_10.SCSI_CDB[3] = 0; /* Reserved */ - CommandMailbox->SCSI_10.SCSI_CDB[4] = - sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T); - CommandMailbox->SCSI_10.SCSI_CDB[5] = 0; /* Control */ - CommandMailbox->SCSI_10.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentDataPointer = - Controller->V2.NewInquiryUnitSerialNumberDMA; - CommandMailbox->SCSI_10.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentByteCount = - CommandMailbox->SCSI_10.DataTransferSize; -} - - -/* - DAC960_V2_NewUnitSerialNumber executes an SCSI pass-through - Inquiry command to a SCSI device identified by Channel number, - Target id, Logical Unit Number. This function Waits for completion - of the command. - - The return data includes Unit Serial Number information for the - specified device. - - Data is stored in the controller's V2.NewPhysicalDeviceInfo dma-able - memory buffer. -*/ - -static bool DAC960_V2_NewInquiryUnitSerialNumber(DAC960_Controller_T *Controller, - int Channel, int TargetID, int LogicalUnit) -{ - DAC960_Command_T *Command; - DAC960_V2_CommandMailbox_T *CommandMailbox; - DAC960_V2_CommandStatus_T CommandStatus; - - Command = DAC960_AllocateCommand(Controller); - CommandMailbox = &Command->V2.CommandMailbox; - DAC960_V2_ClearCommand(Command); - Command->CommandType = DAC960_ImmediateCommand; - - DAC960_V2_ConstructNewUnitSerialNumber(Controller, CommandMailbox, - Channel, TargetID, LogicalUnit); - - DAC960_ExecuteCommand(Command); - CommandStatus = Command->V2.CommandStatus; - DAC960_DeallocateCommand(Command); - return (CommandStatus == DAC960_V2_NormalCompletion); -} - - -/* - DAC960_V2_DeviceOperation executes a DAC960 V2 Firmware Controller Device - Operation IOCTL Command and waits for completion. It returns true on - success and false on failure. -*/ - -static bool DAC960_V2_DeviceOperation(DAC960_Controller_T *Controller, - DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode, - DAC960_V2_OperationDevice_T - OperationDevice) -{ - DAC960_Command_T *Command = DAC960_AllocateCommand(Controller); - DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; - DAC960_V2_CommandStatus_T CommandStatus; - DAC960_V2_ClearCommand(Command); - Command->CommandType = DAC960_ImmediateCommand; - CommandMailbox->DeviceOperation.CommandOpcode = DAC960_V2_IOCTL; - CommandMailbox->DeviceOperation.CommandControlBits - .DataTransferControllerToHost = true; - CommandMailbox->DeviceOperation.CommandControlBits - .NoAutoRequestSense = true; - CommandMailbox->DeviceOperation.IOCTL_Opcode = IOCTL_Opcode; - CommandMailbox->DeviceOperation.OperationDevice = OperationDevice; - DAC960_ExecuteCommand(Command); - CommandStatus = Command->V2.CommandStatus; - DAC960_DeallocateCommand(Command); - return (CommandStatus == DAC960_V2_NormalCompletion); -} - - -/* - DAC960_V1_EnableMemoryMailboxInterface enables the Memory Mailbox Interface - for DAC960 V1 Firmware Controllers. - - PD and P controller types have no memory mailbox, but still need the - other dma mapped memory. -*/ - -static bool DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T - *Controller) -{ - void __iomem *ControllerBaseAddress = Controller->BaseAddress; - DAC960_HardwareType_T hw_type = Controller->HardwareType; - struct pci_dev *PCI_Device = Controller->PCIDevice; - struct dma_loaf *DmaPages = &Controller->DmaPages; - size_t DmaPagesSize; - size_t CommandMailboxesSize; - size_t StatusMailboxesSize; - - DAC960_V1_CommandMailbox_T *CommandMailboxesMemory; - dma_addr_t CommandMailboxesMemoryDMA; - - DAC960_V1_StatusMailbox_T *StatusMailboxesMemory; - dma_addr_t StatusMailboxesMemoryDMA; - - DAC960_V1_CommandMailbox_T CommandMailbox; - DAC960_V1_CommandStatus_T CommandStatus; - int TimeoutCounter; - int i; - - memset(&CommandMailbox, 0, sizeof(DAC960_V1_CommandMailbox_T)); - - if (pci_set_dma_mask(Controller->PCIDevice, DMA_BIT_MASK(32))) - return DAC960_Failure(Controller, "DMA mask out of range"); - - if ((hw_type == DAC960_PD_Controller) || (hw_type == DAC960_P_Controller)) { - CommandMailboxesSize = 0; - StatusMailboxesSize = 0; - } else { - CommandMailboxesSize = DAC960_V1_CommandMailboxCount * sizeof(DAC960_V1_CommandMailbox_T); - StatusMailboxesSize = DAC960_V1_StatusMailboxCount * sizeof(DAC960_V1_StatusMailbox_T); - } - DmaPagesSize = CommandMailboxesSize + StatusMailboxesSize + - sizeof(DAC960_V1_DCDB_T) + sizeof(DAC960_V1_Enquiry_T) + - sizeof(DAC960_V1_ErrorTable_T) + sizeof(DAC960_V1_EventLogEntry_T) + - sizeof(DAC960_V1_RebuildProgress_T) + - sizeof(DAC960_V1_LogicalDriveInformationArray_T) + - sizeof(DAC960_V1_BackgroundInitializationStatus_T) + - sizeof(DAC960_V1_DeviceState_T) + sizeof(DAC960_SCSI_Inquiry_T) + - sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T); - - if (!init_dma_loaf(PCI_Device, DmaPages, DmaPagesSize)) - return false; - - - if ((hw_type == DAC960_PD_Controller) || (hw_type == DAC960_P_Controller)) - goto skip_mailboxes; - - CommandMailboxesMemory = slice_dma_loaf(DmaPages, - CommandMailboxesSize, &CommandMailboxesMemoryDMA); - - /* These are the base addresses for the command memory mailbox array */ - Controller->V1.FirstCommandMailbox = CommandMailboxesMemory; - Controller->V1.FirstCommandMailboxDMA = CommandMailboxesMemoryDMA; - - CommandMailboxesMemory += DAC960_V1_CommandMailboxCount - 1; - Controller->V1.LastCommandMailbox = CommandMailboxesMemory; - Controller->V1.NextCommandMailbox = Controller->V1.FirstCommandMailbox; - Controller->V1.PreviousCommandMailbox1 = Controller->V1.LastCommandMailbox; - Controller->V1.PreviousCommandMailbox2 = - Controller->V1.LastCommandMailbox - 1; - - /* These are the base addresses for the status memory mailbox array */ - StatusMailboxesMemory = slice_dma_loaf(DmaPages, - StatusMailboxesSize, &StatusMailboxesMemoryDMA); - - Controller->V1.FirstStatusMailbox = StatusMailboxesMemory; - Controller->V1.FirstStatusMailboxDMA = StatusMailboxesMemoryDMA; - StatusMailboxesMemory += DAC960_V1_StatusMailboxCount - 1; - Controller->V1.LastStatusMailbox = StatusMailboxesMemory; - Controller->V1.NextStatusMailbox = Controller->V1.FirstStatusMailbox; - -skip_mailboxes: - Controller->V1.MonitoringDCDB = slice_dma_loaf(DmaPages, - sizeof(DAC960_V1_DCDB_T), - &Controller->V1.MonitoringDCDB_DMA); - - Controller->V1.NewEnquiry = slice_dma_loaf(DmaPages, - sizeof(DAC960_V1_Enquiry_T), - &Controller->V1.NewEnquiryDMA); - - Controller->V1.NewErrorTable = slice_dma_loaf(DmaPages, - sizeof(DAC960_V1_ErrorTable_T), - &Controller->V1.NewErrorTableDMA); - - Controller->V1.EventLogEntry = slice_dma_loaf(DmaPages, - sizeof(DAC960_V1_EventLogEntry_T), - &Controller->V1.EventLogEntryDMA); - - Controller->V1.RebuildProgress = slice_dma_loaf(DmaPages, - sizeof(DAC960_V1_RebuildProgress_T), - &Controller->V1.RebuildProgressDMA); - - Controller->V1.NewLogicalDriveInformation = slice_dma_loaf(DmaPages, - sizeof(DAC960_V1_LogicalDriveInformationArray_T), - &Controller->V1.NewLogicalDriveInformationDMA); - - Controller->V1.BackgroundInitializationStatus = slice_dma_loaf(DmaPages, - sizeof(DAC960_V1_BackgroundInitializationStatus_T), - &Controller->V1.BackgroundInitializationStatusDMA); - - Controller->V1.NewDeviceState = slice_dma_loaf(DmaPages, - sizeof(DAC960_V1_DeviceState_T), - &Controller->V1.NewDeviceStateDMA); - - Controller->V1.NewInquiryStandardData = slice_dma_loaf(DmaPages, - sizeof(DAC960_SCSI_Inquiry_T), - &Controller->V1.NewInquiryStandardDataDMA); - - Controller->V1.NewInquiryUnitSerialNumber = slice_dma_loaf(DmaPages, - sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), - &Controller->V1.NewInquiryUnitSerialNumberDMA); - - if ((hw_type == DAC960_PD_Controller) || (hw_type == DAC960_P_Controller)) - return true; - - /* Enable the Memory Mailbox Interface. */ - Controller->V1.DualModeMemoryMailboxInterface = true; - CommandMailbox.TypeX.CommandOpcode = 0x2B; - CommandMailbox.TypeX.CommandIdentifier = 0; - CommandMailbox.TypeX.CommandOpcode2 = 0x14; - CommandMailbox.TypeX.CommandMailboxesBusAddress = - Controller->V1.FirstCommandMailboxDMA; - CommandMailbox.TypeX.StatusMailboxesBusAddress = - Controller->V1.FirstStatusMailboxDMA; -#define TIMEOUT_COUNT 1000000 - - for (i = 0; i < 2; i++) - switch (Controller->HardwareType) - { - case DAC960_LA_Controller: - TimeoutCounter = TIMEOUT_COUNT; - while (--TimeoutCounter >= 0) - { - if (!DAC960_LA_HardwareMailboxFullP(ControllerBaseAddress)) - break; - udelay(10); - } - if (TimeoutCounter < 0) return false; - DAC960_LA_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox); - DAC960_LA_HardwareMailboxNewCommand(ControllerBaseAddress); - TimeoutCounter = TIMEOUT_COUNT; - while (--TimeoutCounter >= 0) - { - if (DAC960_LA_HardwareMailboxStatusAvailableP( - ControllerBaseAddress)) - break; - udelay(10); - } - if (TimeoutCounter < 0) return false; - CommandStatus = DAC960_LA_ReadStatusRegister(ControllerBaseAddress); - DAC960_LA_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress); - DAC960_LA_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress); - if (CommandStatus == DAC960_V1_NormalCompletion) return true; - Controller->V1.DualModeMemoryMailboxInterface = false; - CommandMailbox.TypeX.CommandOpcode2 = 0x10; - break; - case DAC960_PG_Controller: - TimeoutCounter = TIMEOUT_COUNT; - while (--TimeoutCounter >= 0) - { - if (!DAC960_PG_HardwareMailboxFullP(ControllerBaseAddress)) - break; - udelay(10); - } - if (TimeoutCounter < 0) return false; - DAC960_PG_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox); - DAC960_PG_HardwareMailboxNewCommand(ControllerBaseAddress); - - TimeoutCounter = TIMEOUT_COUNT; - while (--TimeoutCounter >= 0) - { - if (DAC960_PG_HardwareMailboxStatusAvailableP( - ControllerBaseAddress)) - break; - udelay(10); - } - if (TimeoutCounter < 0) return false; - CommandStatus = DAC960_PG_ReadStatusRegister(ControllerBaseAddress); - DAC960_PG_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress); - DAC960_PG_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress); - if (CommandStatus == DAC960_V1_NormalCompletion) return true; - Controller->V1.DualModeMemoryMailboxInterface = false; - CommandMailbox.TypeX.CommandOpcode2 = 0x10; - break; - default: - DAC960_Failure(Controller, "Unknown Controller Type\n"); - break; - } - return false; -} - - -/* - DAC960_V2_EnableMemoryMailboxInterface enables the Memory Mailbox Interface - for DAC960 V2 Firmware Controllers. - - Aggregate the space needed for the controller's memory mailbox and - the other data structures that will be targets of dma transfers with - the controller. Allocate a dma-mapped region of memory to hold these - structures. Then, save CPU pointers and dma_addr_t values to reference - the structures that are contained in that region. -*/ - -static bool DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T - *Controller) -{ - void __iomem *ControllerBaseAddress = Controller->BaseAddress; - struct pci_dev *PCI_Device = Controller->PCIDevice; - struct dma_loaf *DmaPages = &Controller->DmaPages; - size_t DmaPagesSize; - size_t CommandMailboxesSize; - size_t StatusMailboxesSize; - - DAC960_V2_CommandMailbox_T *CommandMailboxesMemory; - dma_addr_t CommandMailboxesMemoryDMA; - - DAC960_V2_StatusMailbox_T *StatusMailboxesMemory; - dma_addr_t StatusMailboxesMemoryDMA; - - DAC960_V2_CommandMailbox_T *CommandMailbox; - dma_addr_t CommandMailboxDMA; - DAC960_V2_CommandStatus_T CommandStatus; - - if (pci_set_dma_mask(Controller->PCIDevice, DMA_BIT_MASK(64)) && - pci_set_dma_mask(Controller->PCIDevice, DMA_BIT_MASK(32))) - return DAC960_Failure(Controller, "DMA mask out of range"); - - /* This is a temporary dma mapping, used only in the scope of this function */ - CommandMailbox = pci_alloc_consistent(PCI_Device, - sizeof(DAC960_V2_CommandMailbox_T), &CommandMailboxDMA); - if (CommandMailbox == NULL) - return false; - - CommandMailboxesSize = DAC960_V2_CommandMailboxCount * sizeof(DAC960_V2_CommandMailbox_T); - StatusMailboxesSize = DAC960_V2_StatusMailboxCount * sizeof(DAC960_V2_StatusMailbox_T); - DmaPagesSize = - CommandMailboxesSize + StatusMailboxesSize + - sizeof(DAC960_V2_HealthStatusBuffer_T) + - sizeof(DAC960_V2_ControllerInfo_T) + - sizeof(DAC960_V2_LogicalDeviceInfo_T) + - sizeof(DAC960_V2_PhysicalDeviceInfo_T) + - sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T) + - sizeof(DAC960_V2_Event_T) + - sizeof(DAC960_V2_PhysicalToLogicalDevice_T); - - if (!init_dma_loaf(PCI_Device, DmaPages, DmaPagesSize)) { - pci_free_consistent(PCI_Device, sizeof(DAC960_V2_CommandMailbox_T), - CommandMailbox, CommandMailboxDMA); - return false; - } - - CommandMailboxesMemory = slice_dma_loaf(DmaPages, - CommandMailboxesSize, &CommandMailboxesMemoryDMA); - - /* These are the base addresses for the command memory mailbox array */ - Controller->V2.FirstCommandMailbox = CommandMailboxesMemory; - Controller->V2.FirstCommandMailboxDMA = CommandMailboxesMemoryDMA; - - CommandMailboxesMemory += DAC960_V2_CommandMailboxCount - 1; - Controller->V2.LastCommandMailbox = CommandMailboxesMemory; - Controller->V2.NextCommandMailbox = Controller->V2.FirstCommandMailbox; - Controller->V2.PreviousCommandMailbox1 = Controller->V2.LastCommandMailbox; - Controller->V2.PreviousCommandMailbox2 = - Controller->V2.LastCommandMailbox - 1; - - /* These are the base addresses for the status memory mailbox array */ - StatusMailboxesMemory = slice_dma_loaf(DmaPages, - StatusMailboxesSize, &StatusMailboxesMemoryDMA); - - Controller->V2.FirstStatusMailbox = StatusMailboxesMemory; - Controller->V2.FirstStatusMailboxDMA = StatusMailboxesMemoryDMA; - StatusMailboxesMemory += DAC960_V2_StatusMailboxCount - 1; - Controller->V2.LastStatusMailbox = StatusMailboxesMemory; - Controller->V2.NextStatusMailbox = Controller->V2.FirstStatusMailbox; - - Controller->V2.HealthStatusBuffer = slice_dma_loaf(DmaPages, - sizeof(DAC960_V2_HealthStatusBuffer_T), - &Controller->V2.HealthStatusBufferDMA); - - Controller->V2.NewControllerInformation = slice_dma_loaf(DmaPages, - sizeof(DAC960_V2_ControllerInfo_T), - &Controller->V2.NewControllerInformationDMA); - - Controller->V2.NewLogicalDeviceInformation = slice_dma_loaf(DmaPages, - sizeof(DAC960_V2_LogicalDeviceInfo_T), - &Controller->V2.NewLogicalDeviceInformationDMA); - - Controller->V2.NewPhysicalDeviceInformation = slice_dma_loaf(DmaPages, - sizeof(DAC960_V2_PhysicalDeviceInfo_T), - &Controller->V2.NewPhysicalDeviceInformationDMA); - - Controller->V2.NewInquiryUnitSerialNumber = slice_dma_loaf(DmaPages, - sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), - &Controller->V2.NewInquiryUnitSerialNumberDMA); - - Controller->V2.Event = slice_dma_loaf(DmaPages, - sizeof(DAC960_V2_Event_T), - &Controller->V2.EventDMA); - - Controller->V2.PhysicalToLogicalDevice = slice_dma_loaf(DmaPages, - sizeof(DAC960_V2_PhysicalToLogicalDevice_T), - &Controller->V2.PhysicalToLogicalDeviceDMA); - - /* - Enable the Memory Mailbox Interface. - - I don't know why we can't just use one of the memory mailboxes - we just allocated to do this, instead of using this temporary one. - Try this change later. - */ - memset(CommandMailbox, 0, sizeof(DAC960_V2_CommandMailbox_T)); - CommandMailbox->SetMemoryMailbox.CommandIdentifier = 1; - CommandMailbox->SetMemoryMailbox.CommandOpcode = DAC960_V2_IOCTL; - CommandMailbox->SetMemoryMailbox.CommandControlBits.NoAutoRequestSense = true; - CommandMailbox->SetMemoryMailbox.FirstCommandMailboxSizeKB = - (DAC960_V2_CommandMailboxCount * sizeof(DAC960_V2_CommandMailbox_T)) >> 10; - CommandMailbox->SetMemoryMailbox.FirstStatusMailboxSizeKB = - (DAC960_V2_StatusMailboxCount * sizeof(DAC960_V2_StatusMailbox_T)) >> 10; - CommandMailbox->SetMemoryMailbox.SecondCommandMailboxSizeKB = 0; - CommandMailbox->SetMemoryMailbox.SecondStatusMailboxSizeKB = 0; - CommandMailbox->SetMemoryMailbox.RequestSenseSize = 0; - CommandMailbox->SetMemoryMailbox.IOCTL_Opcode = DAC960_V2_SetMemoryMailbox; - CommandMailbox->SetMemoryMailbox.HealthStatusBufferSizeKB = 1; - CommandMailbox->SetMemoryMailbox.HealthStatusBufferBusAddress = - Controller->V2.HealthStatusBufferDMA; - CommandMailbox->SetMemoryMailbox.FirstCommandMailboxBusAddress = - Controller->V2.FirstCommandMailboxDMA; - CommandMailbox->SetMemoryMailbox.FirstStatusMailboxBusAddress = - Controller->V2.FirstStatusMailboxDMA; - switch (Controller->HardwareType) - { - case DAC960_GEM_Controller: - while (DAC960_GEM_HardwareMailboxFullP(ControllerBaseAddress)) - udelay(1); - DAC960_GEM_WriteHardwareMailbox(ControllerBaseAddress, CommandMailboxDMA); - DAC960_GEM_HardwareMailboxNewCommand(ControllerBaseAddress); - while (!DAC960_GEM_HardwareMailboxStatusAvailableP(ControllerBaseAddress)) - udelay(1); - CommandStatus = DAC960_GEM_ReadCommandStatus(ControllerBaseAddress); - DAC960_GEM_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress); - DAC960_GEM_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress); - break; - case DAC960_BA_Controller: - while (DAC960_BA_HardwareMailboxFullP(ControllerBaseAddress)) - udelay(1); - DAC960_BA_WriteHardwareMailbox(ControllerBaseAddress, CommandMailboxDMA); - DAC960_BA_HardwareMailboxNewCommand(ControllerBaseAddress); - while (!DAC960_BA_HardwareMailboxStatusAvailableP(ControllerBaseAddress)) - udelay(1); - CommandStatus = DAC960_BA_ReadCommandStatus(ControllerBaseAddress); - DAC960_BA_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress); - DAC960_BA_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress); - break; - case DAC960_LP_Controller: - while (DAC960_LP_HardwareMailboxFullP(ControllerBaseAddress)) - udelay(1); - DAC960_LP_WriteHardwareMailbox(ControllerBaseAddress, CommandMailboxDMA); - DAC960_LP_HardwareMailboxNewCommand(ControllerBaseAddress); - while (!DAC960_LP_HardwareMailboxStatusAvailableP(ControllerBaseAddress)) - udelay(1); - CommandStatus = DAC960_LP_ReadCommandStatus(ControllerBaseAddress); - DAC960_LP_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress); - DAC960_LP_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress); - break; - default: - DAC960_Failure(Controller, "Unknown Controller Type\n"); - CommandStatus = DAC960_V2_AbormalCompletion; - break; - } - pci_free_consistent(PCI_Device, sizeof(DAC960_V2_CommandMailbox_T), - CommandMailbox, CommandMailboxDMA); - return (CommandStatus == DAC960_V2_NormalCompletion); -} - - -/* - DAC960_V1_ReadControllerConfiguration reads the Configuration Information - from DAC960 V1 Firmware Controllers and initializes the Controller structure. -*/ - -static bool DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T - *Controller) -{ - DAC960_V1_Enquiry2_T *Enquiry2; - dma_addr_t Enquiry2DMA; - DAC960_V1_Config2_T *Config2; - dma_addr_t Config2DMA; - int LogicalDriveNumber, Channel, TargetID; - struct dma_loaf local_dma; - - if (!init_dma_loaf(Controller->PCIDevice, &local_dma, - sizeof(DAC960_V1_Enquiry2_T) + sizeof(DAC960_V1_Config2_T))) - return DAC960_Failure(Controller, "LOGICAL DEVICE ALLOCATION"); - - Enquiry2 = slice_dma_loaf(&local_dma, sizeof(DAC960_V1_Enquiry2_T), &Enquiry2DMA); - Config2 = slice_dma_loaf(&local_dma, sizeof(DAC960_V1_Config2_T), &Config2DMA); - - if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry, - Controller->V1.NewEnquiryDMA)) { - free_dma_loaf(Controller->PCIDevice, &local_dma); - return DAC960_Failure(Controller, "ENQUIRY"); - } - memcpy(&Controller->V1.Enquiry, Controller->V1.NewEnquiry, - sizeof(DAC960_V1_Enquiry_T)); - - if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry2, Enquiry2DMA)) { - free_dma_loaf(Controller->PCIDevice, &local_dma); - return DAC960_Failure(Controller, "ENQUIRY2"); - } - - if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_ReadConfig2, Config2DMA)) { - free_dma_loaf(Controller->PCIDevice, &local_dma); - return DAC960_Failure(Controller, "READ CONFIG2"); - } - - if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_GetLogicalDriveInformation, - Controller->V1.NewLogicalDriveInformationDMA)) { - free_dma_loaf(Controller->PCIDevice, &local_dma); - return DAC960_Failure(Controller, "GET LOGICAL DRIVE INFORMATION"); - } - memcpy(&Controller->V1.LogicalDriveInformation, - Controller->V1.NewLogicalDriveInformation, - sizeof(DAC960_V1_LogicalDriveInformationArray_T)); - - for (Channel = 0; Channel < Enquiry2->ActualChannels; Channel++) - for (TargetID = 0; TargetID < Enquiry2->MaxTargets; TargetID++) { - if (!DAC960_V1_ExecuteType3D(Controller, DAC960_V1_GetDeviceState, - Channel, TargetID, - Controller->V1.NewDeviceStateDMA)) { - free_dma_loaf(Controller->PCIDevice, &local_dma); - return DAC960_Failure(Controller, "GET DEVICE STATE"); - } - memcpy(&Controller->V1.DeviceState[Channel][TargetID], - Controller->V1.NewDeviceState, sizeof(DAC960_V1_DeviceState_T)); - } - /* - Initialize the Controller Model Name and Full Model Name fields. - */ - switch (Enquiry2->HardwareID.SubModel) - { - case DAC960_V1_P_PD_PU: - if (Enquiry2->SCSICapability.BusSpeed == DAC960_V1_Ultra) - strcpy(Controller->ModelName, "DAC960PU"); - else strcpy(Controller->ModelName, "DAC960PD"); - break; - case DAC960_V1_PL: - strcpy(Controller->ModelName, "DAC960PL"); - break; - case DAC960_V1_PG: - strcpy(Controller->ModelName, "DAC960PG"); - break; - case DAC960_V1_PJ: - strcpy(Controller->ModelName, "DAC960PJ"); - break; - case DAC960_V1_PR: - strcpy(Controller->ModelName, "DAC960PR"); - break; - case DAC960_V1_PT: - strcpy(Controller->ModelName, "DAC960PT"); - break; - case DAC960_V1_PTL0: - strcpy(Controller->ModelName, "DAC960PTL0"); - break; - case DAC960_V1_PRL: - strcpy(Controller->ModelName, "DAC960PRL"); - break; - case DAC960_V1_PTL1: - strcpy(Controller->ModelName, "DAC960PTL1"); - break; - case DAC960_V1_1164P: - strcpy(Controller->ModelName, "DAC1164P"); - break; - default: - free_dma_loaf(Controller->PCIDevice, &local_dma); - return DAC960_Failure(Controller, "MODEL VERIFICATION"); - } - strcpy(Controller->FullModelName, "Mylex "); - strcat(Controller->FullModelName, Controller->ModelName); - /* - Initialize the Controller Firmware Version field and verify that it - is a supported firmware version. The supported firmware versions are: - - DAC1164P 5.06 and above - DAC960PTL/PRL/PJ/PG 4.06 and above - DAC960PU/PD/PL 3.51 and above - DAC960PU/PD/PL/P 2.73 and above - */ -#if defined(CONFIG_ALPHA) - /* - DEC Alpha machines were often equipped with DAC960 cards that were - OEMed from Mylex, and had their own custom firmware. Version 2.70, - the last custom FW revision to be released by DEC for these older - controllers, appears to work quite well with this driver. - - Cards tested successfully were several versions each of the PD and - PU, called by DEC the KZPSC and KZPAC, respectively, and having - the Manufacturer Numbers (from Mylex), usually on a sticker on the - back of the board, of: - - KZPSC: D040347 (1-channel) or D040348 (2-channel) or D040349 (3-channel) - KZPAC: D040395 (1-channel) or D040396 (2-channel) or D040397 (3-channel) - */ -# define FIRMWARE_27X "2.70" -#else -# define FIRMWARE_27X "2.73" -#endif - - if (Enquiry2->FirmwareID.MajorVersion == 0) - { - Enquiry2->FirmwareID.MajorVersion = - Controller->V1.Enquiry.MajorFirmwareVersion; - Enquiry2->FirmwareID.MinorVersion = - Controller->V1.Enquiry.MinorFirmwareVersion; - Enquiry2->FirmwareID.FirmwareType = '0'; - Enquiry2->FirmwareID.TurnID = 0; - } - snprintf(Controller->FirmwareVersion, sizeof(Controller->FirmwareVersion), - "%d.%02d-%c-%02d", - Enquiry2->FirmwareID.MajorVersion, - Enquiry2->FirmwareID.MinorVersion, - Enquiry2->FirmwareID.FirmwareType, - Enquiry2->FirmwareID.TurnID); - if (!((Controller->FirmwareVersion[0] == '5' && - strcmp(Controller->FirmwareVersion, "5.06") >= 0) || - (Controller->FirmwareVersion[0] == '4' && - strcmp(Controller->FirmwareVersion, "4.06") >= 0) || - (Controller->FirmwareVersion[0] == '3' && - strcmp(Controller->FirmwareVersion, "3.51") >= 0) || - (Controller->FirmwareVersion[0] == '2' && - strcmp(Controller->FirmwareVersion, FIRMWARE_27X) >= 0))) - { - DAC960_Failure(Controller, "FIRMWARE VERSION VERIFICATION"); - DAC960_Error("Firmware Version = '%s'\n", Controller, - Controller->FirmwareVersion); - free_dma_loaf(Controller->PCIDevice, &local_dma); - return false; - } - /* - Initialize the Controller Channels, Targets, Memory Size, and SAF-TE - Enclosure Management Enabled fields. - */ - Controller->Channels = Enquiry2->ActualChannels; - Controller->Targets = Enquiry2->MaxTargets; - Controller->MemorySize = Enquiry2->MemorySize >> 20; - Controller->V1.SAFTE_EnclosureManagementEnabled = - (Enquiry2->FaultManagementType == DAC960_V1_SAFTE); - /* - Initialize the Controller Queue Depth, Driver Queue Depth, Logical Drive - Count, Maximum Blocks per Command, Controller Scatter/Gather Limit, and - Driver Scatter/Gather Limit. The Driver Queue Depth must be at most one - less than the Controller Queue Depth to allow for an automatic drive - rebuild operation. - */ - Controller->ControllerQueueDepth = Controller->V1.Enquiry.MaxCommands; - Controller->DriverQueueDepth = Controller->ControllerQueueDepth - 1; - if (Controller->DriverQueueDepth > DAC960_MaxDriverQueueDepth) - Controller->DriverQueueDepth = DAC960_MaxDriverQueueDepth; - Controller->LogicalDriveCount = - Controller->V1.Enquiry.NumberOfLogicalDrives; - Controller->MaxBlocksPerCommand = Enquiry2->MaxBlocksPerCommand; - Controller->ControllerScatterGatherLimit = Enquiry2->MaxScatterGatherEntries; - Controller->DriverScatterGatherLimit = - Controller->ControllerScatterGatherLimit; - if (Controller->DriverScatterGatherLimit > DAC960_V1_ScatterGatherLimit) - Controller->DriverScatterGatherLimit = DAC960_V1_ScatterGatherLimit; - /* - Initialize the Stripe Size, Segment Size, and Geometry Translation. - */ - Controller->V1.StripeSize = Config2->BlocksPerStripe * Config2->BlockFactor - >> (10 - DAC960_BlockSizeBits); - Controller->V1.SegmentSize = Config2->BlocksPerCacheLine * Config2->BlockFactor - >> (10 - DAC960_BlockSizeBits); - switch (Config2->DriveGeometry) - { - case DAC960_V1_Geometry_128_32: - Controller->V1.GeometryTranslationHeads = 128; - Controller->V1.GeometryTranslationSectors = 32; - break; - case DAC960_V1_Geometry_255_63: - Controller->V1.GeometryTranslationHeads = 255; - Controller->V1.GeometryTranslationSectors = 63; - break; - default: - free_dma_loaf(Controller->PCIDevice, &local_dma); - return DAC960_Failure(Controller, "CONFIG2 DRIVE GEOMETRY"); - } - /* - Initialize the Background Initialization Status. - */ - if ((Controller->FirmwareVersion[0] == '4' && - strcmp(Controller->FirmwareVersion, "4.08") >= 0) || - (Controller->FirmwareVersion[0] == '5' && - strcmp(Controller->FirmwareVersion, "5.08") >= 0)) - { - Controller->V1.BackgroundInitializationStatusSupported = true; - DAC960_V1_ExecuteType3B(Controller, - DAC960_V1_BackgroundInitializationControl, 0x20, - Controller-> - V1.BackgroundInitializationStatusDMA); - memcpy(&Controller->V1.LastBackgroundInitializationStatus, - Controller->V1.BackgroundInitializationStatus, - sizeof(DAC960_V1_BackgroundInitializationStatus_T)); - } - /* - Initialize the Logical Drive Initially Accessible flag. - */ - for (LogicalDriveNumber = 0; - LogicalDriveNumber < Controller->LogicalDriveCount; - LogicalDriveNumber++) - if (Controller->V1.LogicalDriveInformation - [LogicalDriveNumber].LogicalDriveState != - DAC960_V1_LogicalDrive_Offline) - Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber] = true; - Controller->V1.LastRebuildStatus = DAC960_V1_NoRebuildOrCheckInProgress; - free_dma_loaf(Controller->PCIDevice, &local_dma); - return true; -} - - -/* - DAC960_V2_ReadControllerConfiguration reads the Configuration Information - from DAC960 V2 Firmware Controllers and initializes the Controller structure. -*/ - -static bool DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T - *Controller) -{ - DAC960_V2_ControllerInfo_T *ControllerInfo = - &Controller->V2.ControllerInformation; - unsigned short LogicalDeviceNumber = 0; - int ModelNameLength; - - /* Get data into dma-able area, then copy into permanent location */ - if (!DAC960_V2_NewControllerInfo(Controller)) - return DAC960_Failure(Controller, "GET CONTROLLER INFO"); - memcpy(ControllerInfo, Controller->V2.NewControllerInformation, - sizeof(DAC960_V2_ControllerInfo_T)); - - - if (!DAC960_V2_GeneralInfo(Controller)) - return DAC960_Failure(Controller, "GET HEALTH STATUS"); - - /* - Initialize the Controller Model Name and Full Model Name fields. - */ - ModelNameLength = sizeof(ControllerInfo->ControllerName); - if (ModelNameLength > sizeof(Controller->ModelName)-1) - ModelNameLength = sizeof(Controller->ModelName)-1; - memcpy(Controller->ModelName, ControllerInfo->ControllerName, - ModelNameLength); - ModelNameLength--; - while (Controller->ModelName[ModelNameLength] == ' ' || - Controller->ModelName[ModelNameLength] == '\0') - ModelNameLength--; - Controller->ModelName[++ModelNameLength] = '\0'; - strcpy(Controller->FullModelName, "Mylex "); - strcat(Controller->FullModelName, Controller->ModelName); - /* - Initialize the Controller Firmware Version field. - */ - sprintf(Controller->FirmwareVersion, "%d.%02d-%02d", - ControllerInfo->FirmwareMajorVersion, - ControllerInfo->FirmwareMinorVersion, - ControllerInfo->FirmwareTurnNumber); - if (ControllerInfo->FirmwareMajorVersion == 6 && - ControllerInfo->FirmwareMinorVersion == 0 && - ControllerInfo->FirmwareTurnNumber < 1) - { - DAC960_Info("FIRMWARE VERSION %s DOES NOT PROVIDE THE CONTROLLER\n", - Controller, Controller->FirmwareVersion); - DAC960_Info("STATUS MONITORING FUNCTIONALITY NEEDED BY THIS DRIVER.\n", - Controller); - DAC960_Info("PLEASE UPGRADE TO VERSION 6.00-01 OR ABOVE.\n", - Controller); - } - /* - Initialize the Controller Channels, Targets, and Memory Size. - */ - Controller->Channels = ControllerInfo->NumberOfPhysicalChannelsPresent; - Controller->Targets = - ControllerInfo->MaximumTargetsPerChannel - [ControllerInfo->NumberOfPhysicalChannelsPresent-1]; - Controller->MemorySize = ControllerInfo->MemorySizeMB; - /* - Initialize the Controller Queue Depth, Driver Queue Depth, Logical Drive - Count, Maximum Blocks per Command, Controller Scatter/Gather Limit, and - Driver Scatter/Gather Limit. The Driver Queue Depth must be at most one - less than the Controller Queue Depth to allow for an automatic drive - rebuild operation. - */ - Controller->ControllerQueueDepth = ControllerInfo->MaximumParallelCommands; - Controller->DriverQueueDepth = Controller->ControllerQueueDepth - 1; - if (Controller->DriverQueueDepth > DAC960_MaxDriverQueueDepth) - Controller->DriverQueueDepth = DAC960_MaxDriverQueueDepth; - Controller->LogicalDriveCount = ControllerInfo->LogicalDevicesPresent; - Controller->MaxBlocksPerCommand = - ControllerInfo->MaximumDataTransferSizeInBlocks; - Controller->ControllerScatterGatherLimit = - ControllerInfo->MaximumScatterGatherEntries; - Controller->DriverScatterGatherLimit = - Controller->ControllerScatterGatherLimit; - if (Controller->DriverScatterGatherLimit > DAC960_V2_ScatterGatherLimit) - Controller->DriverScatterGatherLimit = DAC960_V2_ScatterGatherLimit; - /* - Initialize the Logical Device Information. - */ - while (true) - { - DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo = - Controller->V2.NewLogicalDeviceInformation; - DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo; - DAC960_V2_PhysicalDevice_T PhysicalDevice; - - if (!DAC960_V2_NewLogicalDeviceInfo(Controller, LogicalDeviceNumber)) - break; - LogicalDeviceNumber = NewLogicalDeviceInfo->LogicalDeviceNumber; - if (LogicalDeviceNumber >= DAC960_MaxLogicalDrives) { - DAC960_Error("DAC960: Logical Drive Number %d not supported\n", - Controller, LogicalDeviceNumber); - break; - } - if (NewLogicalDeviceInfo->DeviceBlockSizeInBytes != DAC960_BlockSize) { - DAC960_Error("DAC960: Logical Drive Block Size %d not supported\n", - Controller, NewLogicalDeviceInfo->DeviceBlockSizeInBytes); - LogicalDeviceNumber++; - continue; - } - PhysicalDevice.Controller = 0; - PhysicalDevice.Channel = NewLogicalDeviceInfo->Channel; - PhysicalDevice.TargetID = NewLogicalDeviceInfo->TargetID; - PhysicalDevice.LogicalUnit = NewLogicalDeviceInfo->LogicalUnit; - Controller->V2.LogicalDriveToVirtualDevice[LogicalDeviceNumber] = - PhysicalDevice; - if (NewLogicalDeviceInfo->LogicalDeviceState != - DAC960_V2_LogicalDevice_Offline) - Controller->LogicalDriveInitiallyAccessible[LogicalDeviceNumber] = true; - LogicalDeviceInfo = kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), - GFP_ATOMIC); - if (LogicalDeviceInfo == NULL) - return DAC960_Failure(Controller, "LOGICAL DEVICE ALLOCATION"); - Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] = - LogicalDeviceInfo; - memcpy(LogicalDeviceInfo, NewLogicalDeviceInfo, - sizeof(DAC960_V2_LogicalDeviceInfo_T)); - LogicalDeviceNumber++; - } - return true; -} - - -/* - DAC960_ReportControllerConfiguration reports the Configuration Information - for Controller. -*/ - -static bool DAC960_ReportControllerConfiguration(DAC960_Controller_T - *Controller) -{ - DAC960_Info("Configuring Mylex %s PCI RAID Controller\n", - Controller, Controller->ModelName); - DAC960_Info(" Firmware Version: %s, Channels: %d, Memory Size: %dMB\n", - Controller, Controller->FirmwareVersion, - Controller->Channels, Controller->MemorySize); - DAC960_Info(" PCI Bus: %d, Device: %d, Function: %d, I/O Address: ", - Controller, Controller->Bus, - Controller->Device, Controller->Function); - if (Controller->IO_Address == 0) - DAC960_Info("Unassigned\n", Controller); - else DAC960_Info("0x%X\n", Controller, Controller->IO_Address); - DAC960_Info(" PCI Address: 0x%X mapped at 0x%lX, IRQ Channel: %d\n", - Controller, Controller->PCI_Address, - (unsigned long) Controller->BaseAddress, - Controller->IRQ_Channel); - DAC960_Info(" Controller Queue Depth: %d, " - "Maximum Blocks per Command: %d\n", - Controller, Controller->ControllerQueueDepth, - Controller->MaxBlocksPerCommand); - DAC960_Info(" Driver Queue Depth: %d, " - "Scatter/Gather Limit: %d of %d Segments\n", - Controller, Controller->DriverQueueDepth, - Controller->DriverScatterGatherLimit, - Controller->ControllerScatterGatherLimit); - if (Controller->FirmwareType == DAC960_V1_Controller) - { - DAC960_Info(" Stripe Size: %dKB, Segment Size: %dKB, " - "BIOS Geometry: %d/%d\n", Controller, - Controller->V1.StripeSize, - Controller->V1.SegmentSize, - Controller->V1.GeometryTranslationHeads, - Controller->V1.GeometryTranslationSectors); - if (Controller->V1.SAFTE_EnclosureManagementEnabled) - DAC960_Info(" SAF-TE Enclosure Management Enabled\n", Controller); - } - return true; -} - - -/* - DAC960_V1_ReadDeviceConfiguration reads the Device Configuration Information - for DAC960 V1 Firmware Controllers by requesting the SCSI Inquiry and SCSI - Inquiry Unit Serial Number information for each device connected to - Controller. -*/ - -static bool DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T - *Controller) -{ - struct dma_loaf local_dma; - - dma_addr_t DCDBs_dma[DAC960_V1_MaxChannels]; - DAC960_V1_DCDB_T *DCDBs_cpu[DAC960_V1_MaxChannels]; - - dma_addr_t SCSI_Inquiry_dma[DAC960_V1_MaxChannels]; - DAC960_SCSI_Inquiry_T *SCSI_Inquiry_cpu[DAC960_V1_MaxChannels]; - - dma_addr_t SCSI_NewInquiryUnitSerialNumberDMA[DAC960_V1_MaxChannels]; - DAC960_SCSI_Inquiry_UnitSerialNumber_T *SCSI_NewInquiryUnitSerialNumberCPU[DAC960_V1_MaxChannels]; - - struct completion Completions[DAC960_V1_MaxChannels]; - unsigned long flags; - int Channel, TargetID; - - if (!init_dma_loaf(Controller->PCIDevice, &local_dma, - DAC960_V1_MaxChannels*(sizeof(DAC960_V1_DCDB_T) + - sizeof(DAC960_SCSI_Inquiry_T) + - sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T)))) - return DAC960_Failure(Controller, - "DMA ALLOCATION FAILED IN ReadDeviceConfiguration"); - - for (Channel = 0; Channel < Controller->Channels; Channel++) { - DCDBs_cpu[Channel] = slice_dma_loaf(&local_dma, - sizeof(DAC960_V1_DCDB_T), DCDBs_dma + Channel); - SCSI_Inquiry_cpu[Channel] = slice_dma_loaf(&local_dma, - sizeof(DAC960_SCSI_Inquiry_T), - SCSI_Inquiry_dma + Channel); - SCSI_NewInquiryUnitSerialNumberCPU[Channel] = slice_dma_loaf(&local_dma, - sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), - SCSI_NewInquiryUnitSerialNumberDMA + Channel); - } - - for (TargetID = 0; TargetID < Controller->Targets; TargetID++) - { - /* - * For each channel, submit a probe for a device on that channel. - * The timeout interval for a device that is present is 10 seconds. - * With this approach, the timeout periods can elapse in parallel - * on each channel. - */ - for (Channel = 0; Channel < Controller->Channels; Channel++) - { - dma_addr_t NewInquiryStandardDataDMA = SCSI_Inquiry_dma[Channel]; - DAC960_V1_DCDB_T *DCDB = DCDBs_cpu[Channel]; - dma_addr_t DCDB_dma = DCDBs_dma[Channel]; - DAC960_Command_T *Command = Controller->Commands[Channel]; - struct completion *Completion = &Completions[Channel]; - - init_completion(Completion); - DAC960_V1_ClearCommand(Command); - Command->CommandType = DAC960_ImmediateCommand; - Command->Completion = Completion; - Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB; - Command->V1.CommandMailbox.Type3.BusAddress = DCDB_dma; - DCDB->Channel = Channel; - DCDB->TargetID = TargetID; - DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem; - DCDB->EarlyStatus = false; - DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds; - DCDB->NoAutomaticRequestSense = false; - DCDB->DisconnectPermitted = true; - DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T); - DCDB->BusAddress = NewInquiryStandardDataDMA; - DCDB->CDBLength = 6; - DCDB->TransferLengthHigh4 = 0; - DCDB->SenseLength = sizeof(DCDB->SenseData); - DCDB->CDB[0] = 0x12; /* INQUIRY */ - DCDB->CDB[1] = 0; /* EVPD = 0 */ - DCDB->CDB[2] = 0; /* Page Code */ - DCDB->CDB[3] = 0; /* Reserved */ - DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_T); - DCDB->CDB[5] = 0; /* Control */ - - spin_lock_irqsave(&Controller->queue_lock, flags); - DAC960_QueueCommand(Command); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - } - /* - * Wait for the problems submitted in the previous loop - * to complete. On the probes that are successful, - * get the serial number of the device that was found. - */ - for (Channel = 0; Channel < Controller->Channels; Channel++) - { - DAC960_SCSI_Inquiry_T *InquiryStandardData = - &Controller->V1.InquiryStandardData[Channel][TargetID]; - DAC960_SCSI_Inquiry_T *NewInquiryStandardData = SCSI_Inquiry_cpu[Channel]; - dma_addr_t NewInquiryUnitSerialNumberDMA = - SCSI_NewInquiryUnitSerialNumberDMA[Channel]; - DAC960_SCSI_Inquiry_UnitSerialNumber_T *NewInquiryUnitSerialNumber = - SCSI_NewInquiryUnitSerialNumberCPU[Channel]; - DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber = - &Controller->V1.InquiryUnitSerialNumber[Channel][TargetID]; - DAC960_Command_T *Command = Controller->Commands[Channel]; - DAC960_V1_DCDB_T *DCDB = DCDBs_cpu[Channel]; - struct completion *Completion = &Completions[Channel]; - - wait_for_completion(Completion); - - if (Command->V1.CommandStatus != DAC960_V1_NormalCompletion) { - memset(InquiryStandardData, 0, sizeof(DAC960_SCSI_Inquiry_T)); - InquiryStandardData->PeripheralDeviceType = 0x1F; - continue; - } else - memcpy(InquiryStandardData, NewInquiryStandardData, sizeof(DAC960_SCSI_Inquiry_T)); - - /* Preserve Channel and TargetID values from the previous loop */ - Command->Completion = Completion; - DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T); - DCDB->BusAddress = NewInquiryUnitSerialNumberDMA; - DCDB->SenseLength = sizeof(DCDB->SenseData); - DCDB->CDB[0] = 0x12; /* INQUIRY */ - DCDB->CDB[1] = 1; /* EVPD = 1 */ - DCDB->CDB[2] = 0x80; /* Page Code */ - DCDB->CDB[3] = 0; /* Reserved */ - DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T); - DCDB->CDB[5] = 0; /* Control */ - - spin_lock_irqsave(&Controller->queue_lock, flags); - DAC960_QueueCommand(Command); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - wait_for_completion(Completion); - - if (Command->V1.CommandStatus != DAC960_V1_NormalCompletion) { - memset(InquiryUnitSerialNumber, 0, - sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T)); - InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F; - } else - memcpy(InquiryUnitSerialNumber, NewInquiryUnitSerialNumber, - sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T)); - } - } - free_dma_loaf(Controller->PCIDevice, &local_dma); - return true; -} - - -/* - DAC960_V2_ReadDeviceConfiguration reads the Device Configuration Information - for DAC960 V2 Firmware Controllers by requesting the Physical Device - Information and SCSI Inquiry Unit Serial Number information for each - device connected to Controller. -*/ - -static bool DAC960_V2_ReadDeviceConfiguration(DAC960_Controller_T - *Controller) -{ - unsigned char Channel = 0, TargetID = 0, LogicalUnit = 0; - unsigned short PhysicalDeviceIndex = 0; - - while (true) - { - DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo = - Controller->V2.NewPhysicalDeviceInformation; - DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo; - DAC960_SCSI_Inquiry_UnitSerialNumber_T *NewInquiryUnitSerialNumber = - Controller->V2.NewInquiryUnitSerialNumber; - DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber; - - if (!DAC960_V2_NewPhysicalDeviceInfo(Controller, Channel, TargetID, LogicalUnit)) - break; - - PhysicalDeviceInfo = kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), - GFP_ATOMIC); - if (PhysicalDeviceInfo == NULL) - return DAC960_Failure(Controller, "PHYSICAL DEVICE ALLOCATION"); - Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex] = - PhysicalDeviceInfo; - memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo, - sizeof(DAC960_V2_PhysicalDeviceInfo_T)); - - InquiryUnitSerialNumber = kmalloc( - sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), GFP_ATOMIC); - if (InquiryUnitSerialNumber == NULL) { - kfree(PhysicalDeviceInfo); - return DAC960_Failure(Controller, "SERIAL NUMBER ALLOCATION"); - } - Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex] = - InquiryUnitSerialNumber; - - Channel = NewPhysicalDeviceInfo->Channel; - TargetID = NewPhysicalDeviceInfo->TargetID; - LogicalUnit = NewPhysicalDeviceInfo->LogicalUnit; - - /* - Some devices do NOT have Unit Serial Numbers. - This command fails for them. But, we still want to - remember those devices are there. Construct a - UnitSerialNumber structure for the failure case. - */ - if (!DAC960_V2_NewInquiryUnitSerialNumber(Controller, Channel, TargetID, LogicalUnit)) { - memset(InquiryUnitSerialNumber, 0, - sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T)); - InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F; - } else - memcpy(InquiryUnitSerialNumber, NewInquiryUnitSerialNumber, - sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T)); - - PhysicalDeviceIndex++; - LogicalUnit++; - } - return true; -} - - -/* - DAC960_SanitizeInquiryData sanitizes the Vendor, Model, Revision, and - Product Serial Number fields of the Inquiry Standard Data and Inquiry - Unit Serial Number structures. -*/ - -static void DAC960_SanitizeInquiryData(DAC960_SCSI_Inquiry_T - *InquiryStandardData, - DAC960_SCSI_Inquiry_UnitSerialNumber_T - *InquiryUnitSerialNumber, - unsigned char *Vendor, - unsigned char *Model, - unsigned char *Revision, - unsigned char *SerialNumber) -{ - int SerialNumberLength, i; - if (InquiryStandardData->PeripheralDeviceType == 0x1F) return; - for (i = 0; i < sizeof(InquiryStandardData->VendorIdentification); i++) - { - unsigned char VendorCharacter = - InquiryStandardData->VendorIdentification[i]; - Vendor[i] = (VendorCharacter >= ' ' && VendorCharacter <= '~' - ? VendorCharacter : ' '); - } - Vendor[sizeof(InquiryStandardData->VendorIdentification)] = '\0'; - for (i = 0; i < sizeof(InquiryStandardData->ProductIdentification); i++) - { - unsigned char ModelCharacter = - InquiryStandardData->ProductIdentification[i]; - Model[i] = (ModelCharacter >= ' ' && ModelCharacter <= '~' - ? ModelCharacter : ' '); - } - Model[sizeof(InquiryStandardData->ProductIdentification)] = '\0'; - for (i = 0; i < sizeof(InquiryStandardData->ProductRevisionLevel); i++) - { - unsigned char RevisionCharacter = - InquiryStandardData->ProductRevisionLevel[i]; - Revision[i] = (RevisionCharacter >= ' ' && RevisionCharacter <= '~' - ? RevisionCharacter : ' '); - } - Revision[sizeof(InquiryStandardData->ProductRevisionLevel)] = '\0'; - if (InquiryUnitSerialNumber->PeripheralDeviceType == 0x1F) return; - SerialNumberLength = InquiryUnitSerialNumber->PageLength; - if (SerialNumberLength > - sizeof(InquiryUnitSerialNumber->ProductSerialNumber)) - SerialNumberLength = sizeof(InquiryUnitSerialNumber->ProductSerialNumber); - for (i = 0; i < SerialNumberLength; i++) - { - unsigned char SerialNumberCharacter = - InquiryUnitSerialNumber->ProductSerialNumber[i]; - SerialNumber[i] = - (SerialNumberCharacter >= ' ' && SerialNumberCharacter <= '~' - ? SerialNumberCharacter : ' '); - } - SerialNumber[SerialNumberLength] = '\0'; -} - - -/* - DAC960_V1_ReportDeviceConfiguration reports the Device Configuration - Information for DAC960 V1 Firmware Controllers. -*/ - -static bool DAC960_V1_ReportDeviceConfiguration(DAC960_Controller_T - *Controller) -{ - int LogicalDriveNumber, Channel, TargetID; - DAC960_Info(" Physical Devices:\n", Controller); - for (Channel = 0; Channel < Controller->Channels; Channel++) - for (TargetID = 0; TargetID < Controller->Targets; TargetID++) - { - DAC960_SCSI_Inquiry_T *InquiryStandardData = - &Controller->V1.InquiryStandardData[Channel][TargetID]; - DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber = - &Controller->V1.InquiryUnitSerialNumber[Channel][TargetID]; - DAC960_V1_DeviceState_T *DeviceState = - &Controller->V1.DeviceState[Channel][TargetID]; - DAC960_V1_ErrorTableEntry_T *ErrorEntry = - &Controller->V1.ErrorTable.ErrorTableEntries[Channel][TargetID]; - char Vendor[1+sizeof(InquiryStandardData->VendorIdentification)]; - char Model[1+sizeof(InquiryStandardData->ProductIdentification)]; - char Revision[1+sizeof(InquiryStandardData->ProductRevisionLevel)]; - char SerialNumber[1+sizeof(InquiryUnitSerialNumber - ->ProductSerialNumber)]; - if (InquiryStandardData->PeripheralDeviceType == 0x1F) continue; - DAC960_SanitizeInquiryData(InquiryStandardData, InquiryUnitSerialNumber, - Vendor, Model, Revision, SerialNumber); - DAC960_Info(" %d:%d%s Vendor: %s Model: %s Revision: %s\n", - Controller, Channel, TargetID, (TargetID < 10 ? " " : ""), - Vendor, Model, Revision); - if (InquiryUnitSerialNumber->PeripheralDeviceType != 0x1F) - DAC960_Info(" Serial Number: %s\n", Controller, SerialNumber); - if (DeviceState->Present && - DeviceState->DeviceType == DAC960_V1_DiskType) - { - if (Controller->V1.DeviceResetCount[Channel][TargetID] > 0) - DAC960_Info(" Disk Status: %s, %u blocks, %d resets\n", - Controller, - (DeviceState->DeviceState == DAC960_V1_Device_Dead - ? "Dead" - : DeviceState->DeviceState - == DAC960_V1_Device_WriteOnly - ? "Write-Only" - : DeviceState->DeviceState - == DAC960_V1_Device_Online - ? "Online" : "Standby"), - DeviceState->DiskSize, - Controller->V1.DeviceResetCount[Channel][TargetID]); - else - DAC960_Info(" Disk Status: %s, %u blocks\n", Controller, - (DeviceState->DeviceState == DAC960_V1_Device_Dead - ? "Dead" - : DeviceState->DeviceState - == DAC960_V1_Device_WriteOnly - ? "Write-Only" - : DeviceState->DeviceState - == DAC960_V1_Device_Online - ? "Online" : "Standby"), - DeviceState->DiskSize); - } - if (ErrorEntry->ParityErrorCount > 0 || - ErrorEntry->SoftErrorCount > 0 || - ErrorEntry->HardErrorCount > 0 || - ErrorEntry->MiscErrorCount > 0) - DAC960_Info(" Errors - Parity: %d, Soft: %d, " - "Hard: %d, Misc: %d\n", Controller, - ErrorEntry->ParityErrorCount, - ErrorEntry->SoftErrorCount, - ErrorEntry->HardErrorCount, - ErrorEntry->MiscErrorCount); - } - DAC960_Info(" Logical Drives:\n", Controller); - for (LogicalDriveNumber = 0; - LogicalDriveNumber < Controller->LogicalDriveCount; - LogicalDriveNumber++) - { - DAC960_V1_LogicalDriveInformation_T *LogicalDriveInformation = - &Controller->V1.LogicalDriveInformation[LogicalDriveNumber]; - DAC960_Info(" /dev/rd/c%dd%d: RAID-%d, %s, %u blocks, %s\n", - Controller, Controller->ControllerNumber, LogicalDriveNumber, - LogicalDriveInformation->RAIDLevel, - (LogicalDriveInformation->LogicalDriveState - == DAC960_V1_LogicalDrive_Online - ? "Online" - : LogicalDriveInformation->LogicalDriveState - == DAC960_V1_LogicalDrive_Critical - ? "Critical" : "Offline"), - LogicalDriveInformation->LogicalDriveSize, - (LogicalDriveInformation->WriteBack - ? "Write Back" : "Write Thru")); - } - return true; -} - - -/* - DAC960_V2_ReportDeviceConfiguration reports the Device Configuration - Information for DAC960 V2 Firmware Controllers. -*/ - -static bool DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T - *Controller) -{ - int PhysicalDeviceIndex, LogicalDriveNumber; - DAC960_Info(" Physical Devices:\n", Controller); - for (PhysicalDeviceIndex = 0; - PhysicalDeviceIndex < DAC960_V2_MaxPhysicalDevices; - PhysicalDeviceIndex++) - { - DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo = - Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex]; - DAC960_SCSI_Inquiry_T *InquiryStandardData = - (DAC960_SCSI_Inquiry_T *) &PhysicalDeviceInfo->SCSI_InquiryData; - DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber = - Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex]; - char Vendor[1+sizeof(InquiryStandardData->VendorIdentification)]; - char Model[1+sizeof(InquiryStandardData->ProductIdentification)]; - char Revision[1+sizeof(InquiryStandardData->ProductRevisionLevel)]; - char SerialNumber[1+sizeof(InquiryUnitSerialNumber->ProductSerialNumber)]; - if (PhysicalDeviceInfo == NULL) break; - DAC960_SanitizeInquiryData(InquiryStandardData, InquiryUnitSerialNumber, - Vendor, Model, Revision, SerialNumber); - DAC960_Info(" %d:%d%s Vendor: %s Model: %s Revision: %s\n", - Controller, - PhysicalDeviceInfo->Channel, - PhysicalDeviceInfo->TargetID, - (PhysicalDeviceInfo->TargetID < 10 ? " " : ""), - Vendor, Model, Revision); - if (PhysicalDeviceInfo->NegotiatedSynchronousMegaTransfers == 0) - DAC960_Info(" %sAsynchronous\n", Controller, - (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16 - ? "Wide " :"")); - else - DAC960_Info(" %sSynchronous at %d MB/sec\n", Controller, - (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16 - ? "Wide " :""), - (PhysicalDeviceInfo->NegotiatedSynchronousMegaTransfers - * PhysicalDeviceInfo->NegotiatedDataWidthBits/8)); - if (InquiryUnitSerialNumber->PeripheralDeviceType != 0x1F) - DAC960_Info(" Serial Number: %s\n", Controller, SerialNumber); - if (PhysicalDeviceInfo->PhysicalDeviceState == - DAC960_V2_Device_Unconfigured) - continue; - DAC960_Info(" Disk Status: %s, %u blocks\n", Controller, - (PhysicalDeviceInfo->PhysicalDeviceState - == DAC960_V2_Device_Online - ? "Online" - : PhysicalDeviceInfo->PhysicalDeviceState - == DAC960_V2_Device_Rebuild - ? "Rebuild" - : PhysicalDeviceInfo->PhysicalDeviceState - == DAC960_V2_Device_Missing - ? "Missing" - : PhysicalDeviceInfo->PhysicalDeviceState - == DAC960_V2_Device_Critical - ? "Critical" - : PhysicalDeviceInfo->PhysicalDeviceState - == DAC960_V2_Device_Dead - ? "Dead" - : PhysicalDeviceInfo->PhysicalDeviceState - == DAC960_V2_Device_SuspectedDead - ? "Suspected-Dead" - : PhysicalDeviceInfo->PhysicalDeviceState - == DAC960_V2_Device_CommandedOffline - ? "Commanded-Offline" - : PhysicalDeviceInfo->PhysicalDeviceState - == DAC960_V2_Device_Standby - ? "Standby" : "Unknown"), - PhysicalDeviceInfo->ConfigurableDeviceSize); - if (PhysicalDeviceInfo->ParityErrors == 0 && - PhysicalDeviceInfo->SoftErrors == 0 && - PhysicalDeviceInfo->HardErrors == 0 && - PhysicalDeviceInfo->MiscellaneousErrors == 0 && - PhysicalDeviceInfo->CommandTimeouts == 0 && - PhysicalDeviceInfo->Retries == 0 && - PhysicalDeviceInfo->Aborts == 0 && - PhysicalDeviceInfo->PredictedFailuresDetected == 0) - continue; - DAC960_Info(" Errors - Parity: %d, Soft: %d, " - "Hard: %d, Misc: %d\n", Controller, - PhysicalDeviceInfo->ParityErrors, - PhysicalDeviceInfo->SoftErrors, - PhysicalDeviceInfo->HardErrors, - PhysicalDeviceInfo->MiscellaneousErrors); - DAC960_Info(" Timeouts: %d, Retries: %d, " - "Aborts: %d, Predicted: %d\n", Controller, - PhysicalDeviceInfo->CommandTimeouts, - PhysicalDeviceInfo->Retries, - PhysicalDeviceInfo->Aborts, - PhysicalDeviceInfo->PredictedFailuresDetected); - } - DAC960_Info(" Logical Drives:\n", Controller); - for (LogicalDriveNumber = 0; - LogicalDriveNumber < DAC960_MaxLogicalDrives; - LogicalDriveNumber++) - { - DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo = - Controller->V2.LogicalDeviceInformation[LogicalDriveNumber]; - static const unsigned char *ReadCacheStatus[] = { - "Read Cache Disabled", - "Read Cache Enabled", - "Read Ahead Enabled", - "Intelligent Read Ahead Enabled", - "-", "-", "-", "-" - }; - static const unsigned char *WriteCacheStatus[] = { - "Write Cache Disabled", - "Logical Device Read Only", - "Write Cache Enabled", - "Intelligent Write Cache Enabled", - "-", "-", "-", "-" - }; - unsigned char *GeometryTranslation; - if (LogicalDeviceInfo == NULL) continue; - switch (LogicalDeviceInfo->DriveGeometry) - { - case DAC960_V2_Geometry_128_32: - GeometryTranslation = "128/32"; - break; - case DAC960_V2_Geometry_255_63: - GeometryTranslation = "255/63"; - break; - default: - GeometryTranslation = "Invalid"; - DAC960_Error("Illegal Logical Device Geometry %d\n", - Controller, LogicalDeviceInfo->DriveGeometry); - break; - } - DAC960_Info(" /dev/rd/c%dd%d: RAID-%d, %s, %u blocks\n", - Controller, Controller->ControllerNumber, LogicalDriveNumber, - LogicalDeviceInfo->RAIDLevel, - (LogicalDeviceInfo->LogicalDeviceState - == DAC960_V2_LogicalDevice_Online - ? "Online" - : LogicalDeviceInfo->LogicalDeviceState - == DAC960_V2_LogicalDevice_Critical - ? "Critical" : "Offline"), - LogicalDeviceInfo->ConfigurableDeviceSize); - DAC960_Info(" Logical Device %s, BIOS Geometry: %s\n", - Controller, - (LogicalDeviceInfo->LogicalDeviceControl - .LogicalDeviceInitialized - ? "Initialized" : "Uninitialized"), - GeometryTranslation); - if (LogicalDeviceInfo->StripeSize == 0) - { - if (LogicalDeviceInfo->CacheLineSize == 0) - DAC960_Info(" Stripe Size: N/A, " - "Segment Size: N/A\n", Controller); - else - DAC960_Info(" Stripe Size: N/A, " - "Segment Size: %dKB\n", Controller, - 1 << (LogicalDeviceInfo->CacheLineSize - 2)); - } - else - { - if (LogicalDeviceInfo->CacheLineSize == 0) - DAC960_Info(" Stripe Size: %dKB, " - "Segment Size: N/A\n", Controller, - 1 << (LogicalDeviceInfo->StripeSize - 2)); - else - DAC960_Info(" Stripe Size: %dKB, " - "Segment Size: %dKB\n", Controller, - 1 << (LogicalDeviceInfo->StripeSize - 2), - 1 << (LogicalDeviceInfo->CacheLineSize - 2)); - } - DAC960_Info(" %s, %s\n", Controller, - ReadCacheStatus[ - LogicalDeviceInfo->LogicalDeviceControl.ReadCache], - WriteCacheStatus[ - LogicalDeviceInfo->LogicalDeviceControl.WriteCache]); - if (LogicalDeviceInfo->SoftErrors > 0 || - LogicalDeviceInfo->CommandsFailed > 0 || - LogicalDeviceInfo->DeferredWriteErrors) - DAC960_Info(" Errors - Soft: %d, Failed: %d, " - "Deferred Write: %d\n", Controller, - LogicalDeviceInfo->SoftErrors, - LogicalDeviceInfo->CommandsFailed, - LogicalDeviceInfo->DeferredWriteErrors); - - } - return true; -} - -/* - DAC960_RegisterBlockDevice registers the Block Device structures - associated with Controller. -*/ - -static bool DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller) -{ - int MajorNumber = DAC960_MAJOR + Controller->ControllerNumber; - int n; - - /* - Register the Block Device Major Number for this DAC960 Controller. - */ - if (register_blkdev(MajorNumber, "dac960") < 0) - return false; - - for (n = 0; n < DAC960_MaxLogicalDrives; n++) { - struct gendisk *disk = Controller->disks[n]; - struct request_queue *RequestQueue; - - /* for now, let all request queues share controller's lock */ - RequestQueue = blk_init_queue(DAC960_RequestFunction,&Controller->queue_lock); - if (!RequestQueue) { - printk("DAC960: failure to allocate request queue\n"); - continue; - } - Controller->RequestQueue[n] = RequestQueue; - RequestQueue->queuedata = Controller; - blk_queue_max_segments(RequestQueue, Controller->DriverScatterGatherLimit); - blk_queue_max_hw_sectors(RequestQueue, Controller->MaxBlocksPerCommand); - disk->queue = RequestQueue; - sprintf(disk->disk_name, "rd/c%dd%d", Controller->ControllerNumber, n); - disk->major = MajorNumber; - disk->first_minor = n << DAC960_MaxPartitionsBits; - disk->fops = &DAC960_BlockDeviceOperations; - } - /* - Indicate the Block Device Registration completed successfully, - */ - return true; -} - - -/* - DAC960_UnregisterBlockDevice unregisters the Block Device structures - associated with Controller. -*/ - -static void DAC960_UnregisterBlockDevice(DAC960_Controller_T *Controller) -{ - int MajorNumber = DAC960_MAJOR + Controller->ControllerNumber; - int disk; - - /* does order matter when deleting gendisk and cleanup in request queue? */ - for (disk = 0; disk < DAC960_MaxLogicalDrives; disk++) { - del_gendisk(Controller->disks[disk]); - blk_cleanup_queue(Controller->RequestQueue[disk]); - Controller->RequestQueue[disk] = NULL; - } - - /* - Unregister the Block Device Major Number for this DAC960 Controller. - */ - unregister_blkdev(MajorNumber, "dac960"); -} - -/* - DAC960_ComputeGenericDiskInfo computes the values for the Generic Disk - Information Partition Sector Counts and Block Sizes. -*/ - -static void DAC960_ComputeGenericDiskInfo(DAC960_Controller_T *Controller) -{ - int disk; - for (disk = 0; disk < DAC960_MaxLogicalDrives; disk++) - set_capacity(Controller->disks[disk], disk_size(Controller, disk)); -} - -/* - DAC960_ReportErrorStatus reports Controller BIOS Messages passed through - the Error Status Register when the driver performs the BIOS handshaking. - It returns true for fatal errors and false otherwise. -*/ - -static bool DAC960_ReportErrorStatus(DAC960_Controller_T *Controller, - unsigned char ErrorStatus, - unsigned char Parameter0, - unsigned char Parameter1) -{ - switch (ErrorStatus) - { - case 0x00: - DAC960_Notice("Physical Device %d:%d Not Responding\n", - Controller, Parameter1, Parameter0); - break; - case 0x08: - if (Controller->DriveSpinUpMessageDisplayed) break; - DAC960_Notice("Spinning Up Drives\n", Controller); - Controller->DriveSpinUpMessageDisplayed = true; - break; - case 0x30: - DAC960_Notice("Configuration Checksum Error\n", Controller); - break; - case 0x60: - DAC960_Notice("Mirror Race Recovery Failed\n", Controller); - break; - case 0x70: - DAC960_Notice("Mirror Race Recovery In Progress\n", Controller); - break; - case 0x90: - DAC960_Notice("Physical Device %d:%d COD Mismatch\n", - Controller, Parameter1, Parameter0); - break; - case 0xA0: - DAC960_Notice("Logical Drive Installation Aborted\n", Controller); - break; - case 0xB0: - DAC960_Notice("Mirror Race On A Critical Logical Drive\n", Controller); - break; - case 0xD0: - DAC960_Notice("New Controller Configuration Found\n", Controller); - break; - case 0xF0: - DAC960_Error("Fatal Memory Parity Error for Controller at\n", Controller); - return true; - default: - DAC960_Error("Unknown Initialization Error %02X for Controller at\n", - Controller, ErrorStatus); - return true; - } - return false; -} - - -/* - * DAC960_DetectCleanup releases the resources that were allocated - * during DAC960_DetectController(). DAC960_DetectController can - * has several internal failure points, so not ALL resources may - * have been allocated. It's important to free only - * resources that HAVE been allocated. The code below always - * tests that the resource has been allocated before attempting to - * free it. - */ -static void DAC960_DetectCleanup(DAC960_Controller_T *Controller) -{ - int i; - - /* Free the memory mailbox, status, and related structures */ - free_dma_loaf(Controller->PCIDevice, &Controller->DmaPages); - if (Controller->MemoryMappedAddress) { - switch(Controller->HardwareType) - { - case DAC960_GEM_Controller: - DAC960_GEM_DisableInterrupts(Controller->BaseAddress); - break; - case DAC960_BA_Controller: - DAC960_BA_DisableInterrupts(Controller->BaseAddress); - break; - case DAC960_LP_Controller: - DAC960_LP_DisableInterrupts(Controller->BaseAddress); - break; - case DAC960_LA_Controller: - DAC960_LA_DisableInterrupts(Controller->BaseAddress); - break; - case DAC960_PG_Controller: - DAC960_PG_DisableInterrupts(Controller->BaseAddress); - break; - case DAC960_PD_Controller: - DAC960_PD_DisableInterrupts(Controller->BaseAddress); - break; - case DAC960_P_Controller: - DAC960_PD_DisableInterrupts(Controller->BaseAddress); - break; - } - iounmap(Controller->MemoryMappedAddress); - } - if (Controller->IRQ_Channel) - free_irq(Controller->IRQ_Channel, Controller); - if (Controller->IO_Address) - release_region(Controller->IO_Address, 0x80); - pci_disable_device(Controller->PCIDevice); - for (i = 0; (i < DAC960_MaxLogicalDrives) && Controller->disks[i]; i++) - put_disk(Controller->disks[i]); - DAC960_Controllers[Controller->ControllerNumber] = NULL; - kfree(Controller); -} - - -/* - DAC960_DetectController detects Mylex DAC960/AcceleRAID/eXtremeRAID - PCI RAID Controllers by interrogating the PCI Configuration Space for - Controller Type. -*/ - -static DAC960_Controller_T * -DAC960_DetectController(struct pci_dev *PCI_Device, - const struct pci_device_id *entry) -{ - struct DAC960_privdata *privdata = - (struct DAC960_privdata *)entry->driver_data; - irq_handler_t InterruptHandler = privdata->InterruptHandler; - unsigned int MemoryWindowSize = privdata->MemoryWindowSize; - DAC960_Controller_T *Controller = NULL; - unsigned char DeviceFunction = PCI_Device->devfn; - unsigned char ErrorStatus, Parameter0, Parameter1; - unsigned int IRQ_Channel; - void __iomem *BaseAddress; - int i; - - Controller = kzalloc(sizeof(DAC960_Controller_T), GFP_ATOMIC); - if (Controller == NULL) { - DAC960_Error("Unable to allocate Controller structure for " - "Controller at\n", NULL); - return NULL; - } - Controller->ControllerNumber = DAC960_ControllerCount; - DAC960_Controllers[DAC960_ControllerCount++] = Controller; - Controller->Bus = PCI_Device->bus->number; - Controller->FirmwareType = privdata->FirmwareType; - Controller->HardwareType = privdata->HardwareType; - Controller->Device = DeviceFunction >> 3; - Controller->Function = DeviceFunction & 0x7; - Controller->PCIDevice = PCI_Device; - strcpy(Controller->FullModelName, "DAC960"); - - if (pci_enable_device(PCI_Device)) - goto Failure; - - switch (Controller->HardwareType) - { - case DAC960_GEM_Controller: - Controller->PCI_Address = pci_resource_start(PCI_Device, 0); - break; - case DAC960_BA_Controller: - Controller->PCI_Address = pci_resource_start(PCI_Device, 0); - break; - case DAC960_LP_Controller: - Controller->PCI_Address = pci_resource_start(PCI_Device, 0); - break; - case DAC960_LA_Controller: - Controller->PCI_Address = pci_resource_start(PCI_Device, 0); - break; - case DAC960_PG_Controller: - Controller->PCI_Address = pci_resource_start(PCI_Device, 0); - break; - case DAC960_PD_Controller: - Controller->IO_Address = pci_resource_start(PCI_Device, 0); - Controller->PCI_Address = pci_resource_start(PCI_Device, 1); - break; - case DAC960_P_Controller: - Controller->IO_Address = pci_resource_start(PCI_Device, 0); - Controller->PCI_Address = pci_resource_start(PCI_Device, 1); - break; - } - - pci_set_drvdata(PCI_Device, (void *)((long)Controller->ControllerNumber)); - for (i = 0; i < DAC960_MaxLogicalDrives; i++) { - Controller->disks[i] = alloc_disk(1<disks[i]) - goto Failure; - Controller->disks[i]->private_data = (void *)((long)i); - } - init_waitqueue_head(&Controller->CommandWaitQueue); - init_waitqueue_head(&Controller->HealthStatusWaitQueue); - spin_lock_init(&Controller->queue_lock); - DAC960_AnnounceDriver(Controller); - /* - Map the Controller Register Window. - */ - if (MemoryWindowSize < PAGE_SIZE) - MemoryWindowSize = PAGE_SIZE; - Controller->MemoryMappedAddress = - ioremap_nocache(Controller->PCI_Address & PAGE_MASK, MemoryWindowSize); - Controller->BaseAddress = - Controller->MemoryMappedAddress + (Controller->PCI_Address & ~PAGE_MASK); - if (Controller->MemoryMappedAddress == NULL) - { - DAC960_Error("Unable to map Controller Register Window for " - "Controller at\n", Controller); - goto Failure; - } - BaseAddress = Controller->BaseAddress; - switch (Controller->HardwareType) - { - case DAC960_GEM_Controller: - DAC960_GEM_DisableInterrupts(BaseAddress); - DAC960_GEM_AcknowledgeHardwareMailboxStatus(BaseAddress); - udelay(1000); - while (DAC960_GEM_InitializationInProgressP(BaseAddress)) - { - if (DAC960_GEM_ReadErrorStatus(BaseAddress, &ErrorStatus, - &Parameter0, &Parameter1) && - DAC960_ReportErrorStatus(Controller, ErrorStatus, - Parameter0, Parameter1)) - goto Failure; - udelay(10); - } - if (!DAC960_V2_EnableMemoryMailboxInterface(Controller)) - { - DAC960_Error("Unable to Enable Memory Mailbox Interface " - "for Controller at\n", Controller); - goto Failure; - } - DAC960_GEM_EnableInterrupts(BaseAddress); - Controller->QueueCommand = DAC960_GEM_QueueCommand; - Controller->ReadControllerConfiguration = - DAC960_V2_ReadControllerConfiguration; - Controller->ReadDeviceConfiguration = - DAC960_V2_ReadDeviceConfiguration; - Controller->ReportDeviceConfiguration = - DAC960_V2_ReportDeviceConfiguration; - Controller->QueueReadWriteCommand = - DAC960_V2_QueueReadWriteCommand; - break; - case DAC960_BA_Controller: - DAC960_BA_DisableInterrupts(BaseAddress); - DAC960_BA_AcknowledgeHardwareMailboxStatus(BaseAddress); - udelay(1000); - while (DAC960_BA_InitializationInProgressP(BaseAddress)) - { - if (DAC960_BA_ReadErrorStatus(BaseAddress, &ErrorStatus, - &Parameter0, &Parameter1) && - DAC960_ReportErrorStatus(Controller, ErrorStatus, - Parameter0, Parameter1)) - goto Failure; - udelay(10); - } - if (!DAC960_V2_EnableMemoryMailboxInterface(Controller)) - { - DAC960_Error("Unable to Enable Memory Mailbox Interface " - "for Controller at\n", Controller); - goto Failure; - } - DAC960_BA_EnableInterrupts(BaseAddress); - Controller->QueueCommand = DAC960_BA_QueueCommand; - Controller->ReadControllerConfiguration = - DAC960_V2_ReadControllerConfiguration; - Controller->ReadDeviceConfiguration = - DAC960_V2_ReadDeviceConfiguration; - Controller->ReportDeviceConfiguration = - DAC960_V2_ReportDeviceConfiguration; - Controller->QueueReadWriteCommand = - DAC960_V2_QueueReadWriteCommand; - break; - case DAC960_LP_Controller: - DAC960_LP_DisableInterrupts(BaseAddress); - DAC960_LP_AcknowledgeHardwareMailboxStatus(BaseAddress); - udelay(1000); - while (DAC960_LP_InitializationInProgressP(BaseAddress)) - { - if (DAC960_LP_ReadErrorStatus(BaseAddress, &ErrorStatus, - &Parameter0, &Parameter1) && - DAC960_ReportErrorStatus(Controller, ErrorStatus, - Parameter0, Parameter1)) - goto Failure; - udelay(10); - } - if (!DAC960_V2_EnableMemoryMailboxInterface(Controller)) - { - DAC960_Error("Unable to Enable Memory Mailbox Interface " - "for Controller at\n", Controller); - goto Failure; - } - DAC960_LP_EnableInterrupts(BaseAddress); - Controller->QueueCommand = DAC960_LP_QueueCommand; - Controller->ReadControllerConfiguration = - DAC960_V2_ReadControllerConfiguration; - Controller->ReadDeviceConfiguration = - DAC960_V2_ReadDeviceConfiguration; - Controller->ReportDeviceConfiguration = - DAC960_V2_ReportDeviceConfiguration; - Controller->QueueReadWriteCommand = - DAC960_V2_QueueReadWriteCommand; - break; - case DAC960_LA_Controller: - DAC960_LA_DisableInterrupts(BaseAddress); - DAC960_LA_AcknowledgeHardwareMailboxStatus(BaseAddress); - udelay(1000); - while (DAC960_LA_InitializationInProgressP(BaseAddress)) - { - if (DAC960_LA_ReadErrorStatus(BaseAddress, &ErrorStatus, - &Parameter0, &Parameter1) && - DAC960_ReportErrorStatus(Controller, ErrorStatus, - Parameter0, Parameter1)) - goto Failure; - udelay(10); - } - if (!DAC960_V1_EnableMemoryMailboxInterface(Controller)) - { - DAC960_Error("Unable to Enable Memory Mailbox Interface " - "for Controller at\n", Controller); - goto Failure; - } - DAC960_LA_EnableInterrupts(BaseAddress); - if (Controller->V1.DualModeMemoryMailboxInterface) - Controller->QueueCommand = DAC960_LA_QueueCommandDualMode; - else Controller->QueueCommand = DAC960_LA_QueueCommandSingleMode; - Controller->ReadControllerConfiguration = - DAC960_V1_ReadControllerConfiguration; - Controller->ReadDeviceConfiguration = - DAC960_V1_ReadDeviceConfiguration; - Controller->ReportDeviceConfiguration = - DAC960_V1_ReportDeviceConfiguration; - Controller->QueueReadWriteCommand = - DAC960_V1_QueueReadWriteCommand; - break; - case DAC960_PG_Controller: - DAC960_PG_DisableInterrupts(BaseAddress); - DAC960_PG_AcknowledgeHardwareMailboxStatus(BaseAddress); - udelay(1000); - while (DAC960_PG_InitializationInProgressP(BaseAddress)) - { - if (DAC960_PG_ReadErrorStatus(BaseAddress, &ErrorStatus, - &Parameter0, &Parameter1) && - DAC960_ReportErrorStatus(Controller, ErrorStatus, - Parameter0, Parameter1)) - goto Failure; - udelay(10); - } - if (!DAC960_V1_EnableMemoryMailboxInterface(Controller)) - { - DAC960_Error("Unable to Enable Memory Mailbox Interface " - "for Controller at\n", Controller); - goto Failure; - } - DAC960_PG_EnableInterrupts(BaseAddress); - if (Controller->V1.DualModeMemoryMailboxInterface) - Controller->QueueCommand = DAC960_PG_QueueCommandDualMode; - else Controller->QueueCommand = DAC960_PG_QueueCommandSingleMode; - Controller->ReadControllerConfiguration = - DAC960_V1_ReadControllerConfiguration; - Controller->ReadDeviceConfiguration = - DAC960_V1_ReadDeviceConfiguration; - Controller->ReportDeviceConfiguration = - DAC960_V1_ReportDeviceConfiguration; - Controller->QueueReadWriteCommand = - DAC960_V1_QueueReadWriteCommand; - break; - case DAC960_PD_Controller: - if (!request_region(Controller->IO_Address, 0x80, - Controller->FullModelName)) { - DAC960_Error("IO port 0x%lx busy for Controller at\n", - Controller, Controller->IO_Address); - goto Failure; - } - DAC960_PD_DisableInterrupts(BaseAddress); - DAC960_PD_AcknowledgeStatus(BaseAddress); - udelay(1000); - while (DAC960_PD_InitializationInProgressP(BaseAddress)) - { - if (DAC960_PD_ReadErrorStatus(BaseAddress, &ErrorStatus, - &Parameter0, &Parameter1) && - DAC960_ReportErrorStatus(Controller, ErrorStatus, - Parameter0, Parameter1)) - goto Failure; - udelay(10); - } - if (!DAC960_V1_EnableMemoryMailboxInterface(Controller)) - { - DAC960_Error("Unable to allocate DMA mapped memory " - "for Controller at\n", Controller); - goto Failure; - } - DAC960_PD_EnableInterrupts(BaseAddress); - Controller->QueueCommand = DAC960_PD_QueueCommand; - Controller->ReadControllerConfiguration = - DAC960_V1_ReadControllerConfiguration; - Controller->ReadDeviceConfiguration = - DAC960_V1_ReadDeviceConfiguration; - Controller->ReportDeviceConfiguration = - DAC960_V1_ReportDeviceConfiguration; - Controller->QueueReadWriteCommand = - DAC960_V1_QueueReadWriteCommand; - break; - case DAC960_P_Controller: - if (!request_region(Controller->IO_Address, 0x80, - Controller->FullModelName)){ - DAC960_Error("IO port 0x%lx busy for Controller at\n", - Controller, Controller->IO_Address); - goto Failure; - } - DAC960_PD_DisableInterrupts(BaseAddress); - DAC960_PD_AcknowledgeStatus(BaseAddress); - udelay(1000); - while (DAC960_PD_InitializationInProgressP(BaseAddress)) - { - if (DAC960_PD_ReadErrorStatus(BaseAddress, &ErrorStatus, - &Parameter0, &Parameter1) && - DAC960_ReportErrorStatus(Controller, ErrorStatus, - Parameter0, Parameter1)) - goto Failure; - udelay(10); - } - if (!DAC960_V1_EnableMemoryMailboxInterface(Controller)) - { - DAC960_Error("Unable to allocate DMA mapped memory" - "for Controller at\n", Controller); - goto Failure; - } - DAC960_PD_EnableInterrupts(BaseAddress); - Controller->QueueCommand = DAC960_P_QueueCommand; - Controller->ReadControllerConfiguration = - DAC960_V1_ReadControllerConfiguration; - Controller->ReadDeviceConfiguration = - DAC960_V1_ReadDeviceConfiguration; - Controller->ReportDeviceConfiguration = - DAC960_V1_ReportDeviceConfiguration; - Controller->QueueReadWriteCommand = - DAC960_V1_QueueReadWriteCommand; - break; - } - /* - Acquire shared access to the IRQ Channel. - */ - IRQ_Channel = PCI_Device->irq; - if (request_irq(IRQ_Channel, InterruptHandler, IRQF_SHARED, - Controller->FullModelName, Controller) < 0) - { - DAC960_Error("Unable to acquire IRQ Channel %d for Controller at\n", - Controller, Controller->IRQ_Channel); - goto Failure; - } - Controller->IRQ_Channel = IRQ_Channel; - Controller->InitialCommand.CommandIdentifier = 1; - Controller->InitialCommand.Controller = Controller; - Controller->Commands[0] = &Controller->InitialCommand; - Controller->FreeCommands = &Controller->InitialCommand; - return Controller; - -Failure: - if (Controller->IO_Address == 0) - DAC960_Error("PCI Bus %d Device %d Function %d I/O Address N/A " - "PCI Address 0x%X\n", Controller, - Controller->Bus, Controller->Device, - Controller->Function, Controller->PCI_Address); - else - DAC960_Error("PCI Bus %d Device %d Function %d I/O Address " - "0x%X PCI Address 0x%X\n", Controller, - Controller->Bus, Controller->Device, - Controller->Function, Controller->IO_Address, - Controller->PCI_Address); - DAC960_DetectCleanup(Controller); - DAC960_ControllerCount--; - return NULL; -} - -/* - DAC960_InitializeController initializes Controller. -*/ - -static bool -DAC960_InitializeController(DAC960_Controller_T *Controller) -{ - if (DAC960_ReadControllerConfiguration(Controller) && - DAC960_ReportControllerConfiguration(Controller) && - DAC960_CreateAuxiliaryStructures(Controller) && - DAC960_ReadDeviceConfiguration(Controller) && - DAC960_ReportDeviceConfiguration(Controller) && - DAC960_RegisterBlockDevice(Controller)) - { - /* - Initialize the Monitoring Timer. - */ - timer_setup(&Controller->MonitoringTimer, - DAC960_MonitoringTimerFunction, 0); - Controller->MonitoringTimer.expires = - jiffies + DAC960_MonitoringTimerInterval; - add_timer(&Controller->MonitoringTimer); - Controller->ControllerInitialized = true; - return true; - } - return false; -} - - -/* - DAC960_FinalizeController finalizes Controller. -*/ - -static void DAC960_FinalizeController(DAC960_Controller_T *Controller) -{ - if (Controller->ControllerInitialized) - { - unsigned long flags; - - /* - * Acquiring and releasing lock here eliminates - * a very low probability race. - * - * The code below allocates controller command structures - * from the free list without holding the controller lock. - * This is safe assuming there is no other activity on - * the controller at the time. - * - * But, there might be a monitoring command still - * in progress. Setting the Shutdown flag while holding - * the lock ensures that there is no monitoring command - * in the interrupt handler currently, and any monitoring - * commands that complete from this time on will NOT return - * their command structure to the free list. - */ - - spin_lock_irqsave(&Controller->queue_lock, flags); - Controller->ShutdownMonitoringTimer = 1; - spin_unlock_irqrestore(&Controller->queue_lock, flags); - - del_timer_sync(&Controller->MonitoringTimer); - if (Controller->FirmwareType == DAC960_V1_Controller) - { - DAC960_Notice("Flushing Cache...", Controller); - DAC960_V1_ExecuteType3(Controller, DAC960_V1_Flush, 0); - DAC960_Notice("done\n", Controller); - - if (Controller->HardwareType == DAC960_PD_Controller) - release_region(Controller->IO_Address, 0x80); - } - else - { - DAC960_Notice("Flushing Cache...", Controller); - DAC960_V2_DeviceOperation(Controller, DAC960_V2_PauseDevice, - DAC960_V2_RAID_Controller); - DAC960_Notice("done\n", Controller); - } - } - DAC960_UnregisterBlockDevice(Controller); - DAC960_DestroyAuxiliaryStructures(Controller); - DAC960_DestroyProcEntries(Controller); - DAC960_DetectCleanup(Controller); -} - - -/* - DAC960_Probe verifies controller's existence and - initializes the DAC960 Driver for that controller. -*/ - -static int -DAC960_Probe(struct pci_dev *dev, const struct pci_device_id *entry) -{ - int disk; - DAC960_Controller_T *Controller; - - if (DAC960_ControllerCount == DAC960_MaxControllers) - { - DAC960_Error("More than %d DAC960 Controllers detected - " - "ignoring from Controller at\n", - NULL, DAC960_MaxControllers); - return -ENODEV; - } - - Controller = DAC960_DetectController(dev, entry); - if (!Controller) - return -ENODEV; - - if (!DAC960_InitializeController(Controller)) { - DAC960_FinalizeController(Controller); - return -ENODEV; - } - - for (disk = 0; disk < DAC960_MaxLogicalDrives; disk++) { - set_capacity(Controller->disks[disk], disk_size(Controller, disk)); - add_disk(Controller->disks[disk]); - } - DAC960_CreateProcEntries(Controller); - return 0; -} - - -/* - DAC960_Finalize finalizes the DAC960 Driver. -*/ - -static void DAC960_Remove(struct pci_dev *PCI_Device) -{ - int Controller_Number = (long)pci_get_drvdata(PCI_Device); - DAC960_Controller_T *Controller = DAC960_Controllers[Controller_Number]; - if (Controller != NULL) - DAC960_FinalizeController(Controller); -} - - -/* - DAC960_V1_QueueReadWriteCommand prepares and queues a Read/Write Command for - DAC960 V1 Firmware Controllers. -*/ - -static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *Command) -{ - DAC960_Controller_T *Controller = Command->Controller; - DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox; - DAC960_V1_ScatterGatherSegment_T *ScatterGatherList = - Command->V1.ScatterGatherList; - struct scatterlist *ScatterList = Command->V1.ScatterList; - - DAC960_V1_ClearCommand(Command); - - if (Command->SegmentCount == 1) - { - if (Command->DmaDirection == PCI_DMA_FROMDEVICE) - CommandMailbox->Type5.CommandOpcode = DAC960_V1_Read; - else - CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write; - - CommandMailbox->Type5.LD.TransferLength = Command->BlockCount; - CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber; - CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber; - CommandMailbox->Type5.BusAddress = - (DAC960_BusAddress32_T)sg_dma_address(ScatterList); - } - else - { - int i; - - if (Command->DmaDirection == PCI_DMA_FROMDEVICE) - CommandMailbox->Type5.CommandOpcode = DAC960_V1_ReadWithScatterGather; - else - CommandMailbox->Type5.CommandOpcode = DAC960_V1_WriteWithScatterGather; - - CommandMailbox->Type5.LD.TransferLength = Command->BlockCount; - CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber; - CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber; - CommandMailbox->Type5.BusAddress = Command->V1.ScatterGatherListDMA; - - CommandMailbox->Type5.ScatterGatherCount = Command->SegmentCount; - - for (i = 0; i < Command->SegmentCount; i++, ScatterList++, ScatterGatherList++) { - ScatterGatherList->SegmentDataPointer = - (DAC960_BusAddress32_T)sg_dma_address(ScatterList); - ScatterGatherList->SegmentByteCount = - (DAC960_ByteCount32_T)sg_dma_len(ScatterList); - } - } - DAC960_QueueCommand(Command); -} - - -/* - DAC960_V2_QueueReadWriteCommand prepares and queues a Read/Write Command for - DAC960 V2 Firmware Controllers. -*/ - -static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *Command) -{ - DAC960_Controller_T *Controller = Command->Controller; - DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; - struct scatterlist *ScatterList = Command->V2.ScatterList; - - DAC960_V2_ClearCommand(Command); - - CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10; - CommandMailbox->SCSI_10.CommandControlBits.DataTransferControllerToHost = - (Command->DmaDirection == PCI_DMA_FROMDEVICE); - CommandMailbox->SCSI_10.DataTransferSize = - Command->BlockCount << DAC960_BlockSizeBits; - CommandMailbox->SCSI_10.RequestSenseBusAddress = Command->V2.RequestSenseDMA; - CommandMailbox->SCSI_10.PhysicalDevice = - Controller->V2.LogicalDriveToVirtualDevice[Command->LogicalDriveNumber]; - CommandMailbox->SCSI_10.RequestSenseSize = sizeof(DAC960_SCSI_RequestSense_T); - CommandMailbox->SCSI_10.CDBLength = 10; - CommandMailbox->SCSI_10.SCSI_CDB[0] = - (Command->DmaDirection == PCI_DMA_FROMDEVICE ? 0x28 : 0x2A); - CommandMailbox->SCSI_10.SCSI_CDB[2] = Command->BlockNumber >> 24; - CommandMailbox->SCSI_10.SCSI_CDB[3] = Command->BlockNumber >> 16; - CommandMailbox->SCSI_10.SCSI_CDB[4] = Command->BlockNumber >> 8; - CommandMailbox->SCSI_10.SCSI_CDB[5] = Command->BlockNumber; - CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8; - CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount; - - if (Command->SegmentCount == 1) - { - CommandMailbox->SCSI_10.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentDataPointer = - (DAC960_BusAddress64_T)sg_dma_address(ScatterList); - CommandMailbox->SCSI_10.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentByteCount = - CommandMailbox->SCSI_10.DataTransferSize; - } - else - { - DAC960_V2_ScatterGatherSegment_T *ScatterGatherList; - int i; - - if (Command->SegmentCount > 2) - { - ScatterGatherList = Command->V2.ScatterGatherList; - CommandMailbox->SCSI_10.CommandControlBits - .AdditionalScatterGatherListMemory = true; - CommandMailbox->SCSI_10.DataTransferMemoryAddress - .ExtendedScatterGather.ScatterGatherList0Length = Command->SegmentCount; - CommandMailbox->SCSI_10.DataTransferMemoryAddress - .ExtendedScatterGather.ScatterGatherList0Address = - Command->V2.ScatterGatherListDMA; - } - else - ScatterGatherList = CommandMailbox->SCSI_10.DataTransferMemoryAddress - .ScatterGatherSegments; - - for (i = 0; i < Command->SegmentCount; i++, ScatterList++, ScatterGatherList++) { - ScatterGatherList->SegmentDataPointer = - (DAC960_BusAddress64_T)sg_dma_address(ScatterList); - ScatterGatherList->SegmentByteCount = - (DAC960_ByteCount64_T)sg_dma_len(ScatterList); - } - } - DAC960_QueueCommand(Command); -} - - -static int DAC960_process_queue(DAC960_Controller_T *Controller, struct request_queue *req_q) -{ - struct request *Request; - DAC960_Command_T *Command; - - while(1) { - Request = blk_peek_request(req_q); - if (!Request) - return 1; - - Command = DAC960_AllocateCommand(Controller); - if (Command == NULL) - return 0; - - if (rq_data_dir(Request) == READ) { - Command->DmaDirection = PCI_DMA_FROMDEVICE; - Command->CommandType = DAC960_ReadCommand; - } else { - Command->DmaDirection = PCI_DMA_TODEVICE; - Command->CommandType = DAC960_WriteCommand; - } - Command->Completion = Request->end_io_data; - Command->LogicalDriveNumber = (long)Request->rq_disk->private_data; - Command->BlockNumber = blk_rq_pos(Request); - Command->BlockCount = blk_rq_sectors(Request); - Command->Request = Request; - blk_start_request(Request); - Command->SegmentCount = blk_rq_map_sg(req_q, - Command->Request, Command->cmd_sglist); - /* pci_map_sg MAY change the value of SegCount */ - Command->SegmentCount = pci_map_sg(Controller->PCIDevice, Command->cmd_sglist, - Command->SegmentCount, Command->DmaDirection); - - DAC960_QueueReadWriteCommand(Command); - } -} - -/* - DAC960_ProcessRequest attempts to remove one I/O Request from Controller's - I/O Request Queue and queues it to the Controller. WaitForCommand is true if - this function should wait for a Command to become available if necessary. - This function returns true if an I/O Request was queued and false otherwise. -*/ -static void DAC960_ProcessRequest(DAC960_Controller_T *controller) -{ - int i; - - if (!controller->ControllerInitialized) - return; - - /* Do this better later! */ - for (i = controller->req_q_index; i < DAC960_MaxLogicalDrives; i++) { - struct request_queue *req_q = controller->RequestQueue[i]; - - if (req_q == NULL) - continue; - - if (!DAC960_process_queue(controller, req_q)) { - controller->req_q_index = i; - return; - } - } - - if (controller->req_q_index == 0) - return; - - for (i = 0; i < controller->req_q_index; i++) { - struct request_queue *req_q = controller->RequestQueue[i]; - - if (req_q == NULL) - continue; - - if (!DAC960_process_queue(controller, req_q)) { - controller->req_q_index = i; - return; - } - } -} - - -/* - DAC960_queue_partial_rw extracts one bio from the request already - associated with argument command, and construct a new command block to retry I/O - only on that bio. Queue that command to the controller. - - This function re-uses a previously-allocated Command, - there is no failure mode from trying to allocate a command. -*/ - -static void DAC960_queue_partial_rw(DAC960_Command_T *Command) -{ - DAC960_Controller_T *Controller = Command->Controller; - struct request *Request = Command->Request; - struct request_queue *req_q = Controller->RequestQueue[Command->LogicalDriveNumber]; - - if (Command->DmaDirection == PCI_DMA_FROMDEVICE) - Command->CommandType = DAC960_ReadRetryCommand; - else - Command->CommandType = DAC960_WriteRetryCommand; - - /* - * We could be more efficient with these mapping requests - * and map only the portions that we need. But since this - * code should almost never be called, just go with a - * simple coding. - */ - (void)blk_rq_map_sg(req_q, Command->Request, Command->cmd_sglist); - - (void)pci_map_sg(Controller->PCIDevice, Command->cmd_sglist, 1, Command->DmaDirection); - /* - * Resubmitting the request sector at a time is really tedious. - * But, this should almost never happen. So, we're willing to pay - * this price so that in the end, as much of the transfer is completed - * successfully as possible. - */ - Command->SegmentCount = 1; - Command->BlockNumber = blk_rq_pos(Request); - Command->BlockCount = 1; - DAC960_QueueReadWriteCommand(Command); - return; -} - -/* - DAC960_RequestFunction is the I/O Request Function for DAC960 Controllers. -*/ - -static void DAC960_RequestFunction(struct request_queue *RequestQueue) -{ - DAC960_ProcessRequest(RequestQueue->queuedata); -} - -/* - DAC960_ProcessCompletedBuffer performs completion processing for an - individual Buffer. -*/ - -static inline bool DAC960_ProcessCompletedRequest(DAC960_Command_T *Command, - bool SuccessfulIO) -{ - struct request *Request = Command->Request; - blk_status_t Error = SuccessfulIO ? BLK_STS_OK : BLK_STS_IOERR; - - pci_unmap_sg(Command->Controller->PCIDevice, Command->cmd_sglist, - Command->SegmentCount, Command->DmaDirection); - - if (!__blk_end_request(Request, Error, Command->BlockCount << 9)) { - if (Command->Completion) { - complete(Command->Completion); - Command->Completion = NULL; - } - return true; - } - return false; -} - -/* - DAC960_V1_ReadWriteError prints an appropriate error message for Command - when an error occurs on a Read or Write operation. -*/ - -static void DAC960_V1_ReadWriteError(DAC960_Command_T *Command) -{ - DAC960_Controller_T *Controller = Command->Controller; - unsigned char *CommandName = "UNKNOWN"; - switch (Command->CommandType) - { - case DAC960_ReadCommand: - case DAC960_ReadRetryCommand: - CommandName = "READ"; - break; - case DAC960_WriteCommand: - case DAC960_WriteRetryCommand: - CommandName = "WRITE"; - break; - case DAC960_MonitoringCommand: - case DAC960_ImmediateCommand: - case DAC960_QueuedCommand: - break; - } - switch (Command->V1.CommandStatus) - { - case DAC960_V1_IrrecoverableDataError: - DAC960_Error("Irrecoverable Data Error on %s:\n", - Controller, CommandName); - break; - case DAC960_V1_LogicalDriveNonexistentOrOffline: - DAC960_Error("Logical Drive Nonexistent or Offline on %s:\n", - Controller, CommandName); - break; - case DAC960_V1_AccessBeyondEndOfLogicalDrive: - DAC960_Error("Attempt to Access Beyond End of Logical Drive " - "on %s:\n", Controller, CommandName); - break; - case DAC960_V1_BadDataEncountered: - DAC960_Error("Bad Data Encountered on %s:\n", Controller, CommandName); - break; - default: - DAC960_Error("Unexpected Error Status %04X on %s:\n", - Controller, Command->V1.CommandStatus, CommandName); - break; - } - DAC960_Error(" /dev/rd/c%dd%d: absolute blocks %u..%u\n", - Controller, Controller->ControllerNumber, - Command->LogicalDriveNumber, Command->BlockNumber, - Command->BlockNumber + Command->BlockCount - 1); -} - - -/* - DAC960_V1_ProcessCompletedCommand performs completion processing for Command - for DAC960 V1 Firmware Controllers. -*/ - -static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command) -{ - DAC960_Controller_T *Controller = Command->Controller; - DAC960_CommandType_T CommandType = Command->CommandType; - DAC960_V1_CommandOpcode_T CommandOpcode = - Command->V1.CommandMailbox.Common.CommandOpcode; - DAC960_V1_CommandStatus_T CommandStatus = Command->V1.CommandStatus; - - if (CommandType == DAC960_ReadCommand || - CommandType == DAC960_WriteCommand) - { - -#ifdef FORCE_RETRY_DEBUG - CommandStatus = DAC960_V1_IrrecoverableDataError; -#endif - - if (CommandStatus == DAC960_V1_NormalCompletion) { - - if (!DAC960_ProcessCompletedRequest(Command, true)) - BUG(); - - } else if (CommandStatus == DAC960_V1_IrrecoverableDataError || - CommandStatus == DAC960_V1_BadDataEncountered) - { - /* - * break the command down into pieces and resubmit each - * piece, hoping that some of them will succeed. - */ - DAC960_queue_partial_rw(Command); - return; - } - else - { - if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline) - DAC960_V1_ReadWriteError(Command); - - if (!DAC960_ProcessCompletedRequest(Command, false)) - BUG(); - } - } - else if (CommandType == DAC960_ReadRetryCommand || - CommandType == DAC960_WriteRetryCommand) - { - bool normal_completion; -#ifdef FORCE_RETRY_FAILURE_DEBUG - static int retry_count = 1; -#endif - /* - Perform completion processing for the portion that was - retried, and submit the next portion, if any. - */ - normal_completion = true; - if (CommandStatus != DAC960_V1_NormalCompletion) { - normal_completion = false; - if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline) - DAC960_V1_ReadWriteError(Command); - } - -#ifdef FORCE_RETRY_FAILURE_DEBUG - if (!(++retry_count % 10000)) { - printk("V1 error retry failure test\n"); - normal_completion = false; - DAC960_V1_ReadWriteError(Command); - } -#endif - - if (!DAC960_ProcessCompletedRequest(Command, normal_completion)) { - DAC960_queue_partial_rw(Command); - return; - } - } - - else if (CommandType == DAC960_MonitoringCommand) - { - if (Controller->ShutdownMonitoringTimer) - return; - if (CommandOpcode == DAC960_V1_Enquiry) - { - DAC960_V1_Enquiry_T *OldEnquiry = &Controller->V1.Enquiry; - DAC960_V1_Enquiry_T *NewEnquiry = Controller->V1.NewEnquiry; - unsigned int OldCriticalLogicalDriveCount = - OldEnquiry->CriticalLogicalDriveCount; - unsigned int NewCriticalLogicalDriveCount = - NewEnquiry->CriticalLogicalDriveCount; - if (NewEnquiry->NumberOfLogicalDrives > Controller->LogicalDriveCount) - { - int LogicalDriveNumber = Controller->LogicalDriveCount - 1; - while (++LogicalDriveNumber < NewEnquiry->NumberOfLogicalDrives) - DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) " - "Now Exists\n", Controller, - LogicalDriveNumber, - Controller->ControllerNumber, - LogicalDriveNumber); - Controller->LogicalDriveCount = NewEnquiry->NumberOfLogicalDrives; - DAC960_ComputeGenericDiskInfo(Controller); - } - if (NewEnquiry->NumberOfLogicalDrives < Controller->LogicalDriveCount) - { - int LogicalDriveNumber = NewEnquiry->NumberOfLogicalDrives - 1; - while (++LogicalDriveNumber < Controller->LogicalDriveCount) - DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) " - "No Longer Exists\n", Controller, - LogicalDriveNumber, - Controller->ControllerNumber, - LogicalDriveNumber); - Controller->LogicalDriveCount = NewEnquiry->NumberOfLogicalDrives; - DAC960_ComputeGenericDiskInfo(Controller); - } - if (NewEnquiry->StatusFlags.DeferredWriteError != - OldEnquiry->StatusFlags.DeferredWriteError) - DAC960_Critical("Deferred Write Error Flag is now %s\n", Controller, - (NewEnquiry->StatusFlags.DeferredWriteError - ? "TRUE" : "FALSE")); - if ((NewCriticalLogicalDriveCount > 0 || - NewCriticalLogicalDriveCount != OldCriticalLogicalDriveCount) || - (NewEnquiry->OfflineLogicalDriveCount > 0 || - NewEnquiry->OfflineLogicalDriveCount != - OldEnquiry->OfflineLogicalDriveCount) || - (NewEnquiry->DeadDriveCount > 0 || - NewEnquiry->DeadDriveCount != - OldEnquiry->DeadDriveCount) || - (NewEnquiry->EventLogSequenceNumber != - OldEnquiry->EventLogSequenceNumber) || - Controller->MonitoringTimerCount == 0 || - time_after_eq(jiffies, Controller->SecondaryMonitoringTime - + DAC960_SecondaryMonitoringInterval)) - { - Controller->V1.NeedLogicalDriveInformation = true; - Controller->V1.NewEventLogSequenceNumber = - NewEnquiry->EventLogSequenceNumber; - Controller->V1.NeedErrorTableInformation = true; - Controller->V1.NeedDeviceStateInformation = true; - Controller->V1.StartDeviceStateScan = true; - Controller->V1.NeedBackgroundInitializationStatus = - Controller->V1.BackgroundInitializationStatusSupported; - Controller->SecondaryMonitoringTime = jiffies; - } - if (NewEnquiry->RebuildFlag == DAC960_V1_StandbyRebuildInProgress || - NewEnquiry->RebuildFlag - == DAC960_V1_BackgroundRebuildInProgress || - OldEnquiry->RebuildFlag == DAC960_V1_StandbyRebuildInProgress || - OldEnquiry->RebuildFlag == DAC960_V1_BackgroundRebuildInProgress) - { - Controller->V1.NeedRebuildProgress = true; - Controller->V1.RebuildProgressFirst = - (NewEnquiry->CriticalLogicalDriveCount < - OldEnquiry->CriticalLogicalDriveCount); - } - if (OldEnquiry->RebuildFlag == DAC960_V1_BackgroundCheckInProgress) - switch (NewEnquiry->RebuildFlag) - { - case DAC960_V1_NoStandbyRebuildOrCheckInProgress: - DAC960_Progress("Consistency Check Completed Successfully\n", - Controller); - break; - case DAC960_V1_StandbyRebuildInProgress: - case DAC960_V1_BackgroundRebuildInProgress: - break; - case DAC960_V1_BackgroundCheckInProgress: - Controller->V1.NeedConsistencyCheckProgress = true; - break; - case DAC960_V1_StandbyRebuildCompletedWithError: - DAC960_Progress("Consistency Check Completed with Error\n", - Controller); - break; - case DAC960_V1_BackgroundRebuildOrCheckFailed_DriveFailed: - DAC960_Progress("Consistency Check Failed - " - "Physical Device Failed\n", Controller); - break; - case DAC960_V1_BackgroundRebuildOrCheckFailed_LogicalDriveFailed: - DAC960_Progress("Consistency Check Failed - " - "Logical Drive Failed\n", Controller); - break; - case DAC960_V1_BackgroundRebuildOrCheckFailed_OtherCauses: - DAC960_Progress("Consistency Check Failed - Other Causes\n", - Controller); - break; - case DAC960_V1_BackgroundRebuildOrCheckSuccessfullyTerminated: - DAC960_Progress("Consistency Check Successfully Terminated\n", - Controller); - break; - } - else if (NewEnquiry->RebuildFlag - == DAC960_V1_BackgroundCheckInProgress) - Controller->V1.NeedConsistencyCheckProgress = true; - Controller->MonitoringAlertMode = - (NewEnquiry->CriticalLogicalDriveCount > 0 || - NewEnquiry->OfflineLogicalDriveCount > 0 || - NewEnquiry->DeadDriveCount > 0); - if (NewEnquiry->RebuildFlag > DAC960_V1_BackgroundCheckInProgress) - { - Controller->V1.PendingRebuildFlag = NewEnquiry->RebuildFlag; - Controller->V1.RebuildFlagPending = true; - } - memcpy(&Controller->V1.Enquiry, &Controller->V1.NewEnquiry, - sizeof(DAC960_V1_Enquiry_T)); - } - else if (CommandOpcode == DAC960_V1_PerformEventLogOperation) - { - static char - *DAC960_EventMessages[] = - { "killed because write recovery failed", - "killed because of SCSI bus reset failure", - "killed because of double check condition", - "killed because it was removed", - "killed because of gross error on SCSI chip", - "killed because of bad tag returned from drive", - "killed because of timeout on SCSI command", - "killed because of reset SCSI command issued from system", - "killed because busy or parity error count exceeded limit", - "killed because of 'kill drive' command from system", - "killed because of selection timeout", - "killed due to SCSI phase sequence error", - "killed due to unknown status" }; - DAC960_V1_EventLogEntry_T *EventLogEntry = - Controller->V1.EventLogEntry; - if (EventLogEntry->SequenceNumber == - Controller->V1.OldEventLogSequenceNumber) - { - unsigned char SenseKey = EventLogEntry->SenseKey; - unsigned char AdditionalSenseCode = - EventLogEntry->AdditionalSenseCode; - unsigned char AdditionalSenseCodeQualifier = - EventLogEntry->AdditionalSenseCodeQualifier; - if (SenseKey == DAC960_SenseKey_VendorSpecific && - AdditionalSenseCode == 0x80 && - AdditionalSenseCodeQualifier < - ARRAY_SIZE(DAC960_EventMessages)) - DAC960_Critical("Physical Device %d:%d %s\n", Controller, - EventLogEntry->Channel, - EventLogEntry->TargetID, - DAC960_EventMessages[ - AdditionalSenseCodeQualifier]); - else if (SenseKey == DAC960_SenseKey_UnitAttention && - AdditionalSenseCode == 0x29) - { - if (Controller->MonitoringTimerCount > 0) - Controller->V1.DeviceResetCount[EventLogEntry->Channel] - [EventLogEntry->TargetID]++; - } - else if (!(SenseKey == DAC960_SenseKey_NoSense || - (SenseKey == DAC960_SenseKey_NotReady && - AdditionalSenseCode == 0x04 && - (AdditionalSenseCodeQualifier == 0x01 || - AdditionalSenseCodeQualifier == 0x02)))) - { - DAC960_Critical("Physical Device %d:%d Error Log: " - "Sense Key = %X, ASC = %02X, ASCQ = %02X\n", - Controller, - EventLogEntry->Channel, - EventLogEntry->TargetID, - SenseKey, - AdditionalSenseCode, - AdditionalSenseCodeQualifier); - DAC960_Critical("Physical Device %d:%d Error Log: " - "Information = %02X%02X%02X%02X " - "%02X%02X%02X%02X\n", - Controller, - EventLogEntry->Channel, - EventLogEntry->TargetID, - EventLogEntry->Information[0], - EventLogEntry->Information[1], - EventLogEntry->Information[2], - EventLogEntry->Information[3], - EventLogEntry->CommandSpecificInformation[0], - EventLogEntry->CommandSpecificInformation[1], - EventLogEntry->CommandSpecificInformation[2], - EventLogEntry->CommandSpecificInformation[3]); - } - } - Controller->V1.OldEventLogSequenceNumber++; - } - else if (CommandOpcode == DAC960_V1_GetErrorTable) - { - DAC960_V1_ErrorTable_T *OldErrorTable = &Controller->V1.ErrorTable; - DAC960_V1_ErrorTable_T *NewErrorTable = Controller->V1.NewErrorTable; - int Channel, TargetID; - for (Channel = 0; Channel < Controller->Channels; Channel++) - for (TargetID = 0; TargetID < Controller->Targets; TargetID++) - { - DAC960_V1_ErrorTableEntry_T *NewErrorEntry = - &NewErrorTable->ErrorTableEntries[Channel][TargetID]; - DAC960_V1_ErrorTableEntry_T *OldErrorEntry = - &OldErrorTable->ErrorTableEntries[Channel][TargetID]; - if ((NewErrorEntry->ParityErrorCount != - OldErrorEntry->ParityErrorCount) || - (NewErrorEntry->SoftErrorCount != - OldErrorEntry->SoftErrorCount) || - (NewErrorEntry->HardErrorCount != - OldErrorEntry->HardErrorCount) || - (NewErrorEntry->MiscErrorCount != - OldErrorEntry->MiscErrorCount)) - DAC960_Critical("Physical Device %d:%d Errors: " - "Parity = %d, Soft = %d, " - "Hard = %d, Misc = %d\n", - Controller, Channel, TargetID, - NewErrorEntry->ParityErrorCount, - NewErrorEntry->SoftErrorCount, - NewErrorEntry->HardErrorCount, - NewErrorEntry->MiscErrorCount); - } - memcpy(&Controller->V1.ErrorTable, Controller->V1.NewErrorTable, - sizeof(DAC960_V1_ErrorTable_T)); - } - else if (CommandOpcode == DAC960_V1_GetDeviceState) - { - DAC960_V1_DeviceState_T *OldDeviceState = - &Controller->V1.DeviceState[Controller->V1.DeviceStateChannel] - [Controller->V1.DeviceStateTargetID]; - DAC960_V1_DeviceState_T *NewDeviceState = - Controller->V1.NewDeviceState; - if (NewDeviceState->DeviceState != OldDeviceState->DeviceState) - DAC960_Critical("Physical Device %d:%d is now %s\n", Controller, - Controller->V1.DeviceStateChannel, - Controller->V1.DeviceStateTargetID, - (NewDeviceState->DeviceState - == DAC960_V1_Device_Dead - ? "DEAD" - : NewDeviceState->DeviceState - == DAC960_V1_Device_WriteOnly - ? "WRITE-ONLY" - : NewDeviceState->DeviceState - == DAC960_V1_Device_Online - ? "ONLINE" : "STANDBY")); - if (OldDeviceState->DeviceState == DAC960_V1_Device_Dead && - NewDeviceState->DeviceState != DAC960_V1_Device_Dead) - { - Controller->V1.NeedDeviceInquiryInformation = true; - Controller->V1.NeedDeviceSerialNumberInformation = true; - Controller->V1.DeviceResetCount - [Controller->V1.DeviceStateChannel] - [Controller->V1.DeviceStateTargetID] = 0; - } - memcpy(OldDeviceState, NewDeviceState, - sizeof(DAC960_V1_DeviceState_T)); - } - else if (CommandOpcode == DAC960_V1_GetLogicalDriveInformation) - { - int LogicalDriveNumber; - for (LogicalDriveNumber = 0; - LogicalDriveNumber < Controller->LogicalDriveCount; - LogicalDriveNumber++) - { - DAC960_V1_LogicalDriveInformation_T *OldLogicalDriveInformation = - &Controller->V1.LogicalDriveInformation[LogicalDriveNumber]; - DAC960_V1_LogicalDriveInformation_T *NewLogicalDriveInformation = - &(*Controller->V1.NewLogicalDriveInformation)[LogicalDriveNumber]; - if (NewLogicalDriveInformation->LogicalDriveState != - OldLogicalDriveInformation->LogicalDriveState) - DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) " - "is now %s\n", Controller, - LogicalDriveNumber, - Controller->ControllerNumber, - LogicalDriveNumber, - (NewLogicalDriveInformation->LogicalDriveState - == DAC960_V1_LogicalDrive_Online - ? "ONLINE" - : NewLogicalDriveInformation->LogicalDriveState - == DAC960_V1_LogicalDrive_Critical - ? "CRITICAL" : "OFFLINE")); - if (NewLogicalDriveInformation->WriteBack != - OldLogicalDriveInformation->WriteBack) - DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) " - "is now %s\n", Controller, - LogicalDriveNumber, - Controller->ControllerNumber, - LogicalDriveNumber, - (NewLogicalDriveInformation->WriteBack - ? "WRITE BACK" : "WRITE THRU")); - } - memcpy(&Controller->V1.LogicalDriveInformation, - Controller->V1.NewLogicalDriveInformation, - sizeof(DAC960_V1_LogicalDriveInformationArray_T)); - } - else if (CommandOpcode == DAC960_V1_GetRebuildProgress) - { - unsigned int LogicalDriveNumber = - Controller->V1.RebuildProgress->LogicalDriveNumber; - unsigned int LogicalDriveSize = - Controller->V1.RebuildProgress->LogicalDriveSize; - unsigned int BlocksCompleted = - LogicalDriveSize - Controller->V1.RebuildProgress->RemainingBlocks; - if (CommandStatus == DAC960_V1_NoRebuildOrCheckInProgress && - Controller->V1.LastRebuildStatus == DAC960_V1_NormalCompletion) - CommandStatus = DAC960_V1_RebuildSuccessful; - switch (CommandStatus) - { - case DAC960_V1_NormalCompletion: - Controller->EphemeralProgressMessage = true; - DAC960_Progress("Rebuild in Progress: " - "Logical Drive %d (/dev/rd/c%dd%d) " - "%d%% completed\n", - Controller, LogicalDriveNumber, - Controller->ControllerNumber, - LogicalDriveNumber, - (100 * (BlocksCompleted >> 7)) - / (LogicalDriveSize >> 7)); - Controller->EphemeralProgressMessage = false; - break; - case DAC960_V1_RebuildFailed_LogicalDriveFailure: - DAC960_Progress("Rebuild Failed due to " - "Logical Drive Failure\n", Controller); - break; - case DAC960_V1_RebuildFailed_BadBlocksOnOther: - DAC960_Progress("Rebuild Failed due to " - "Bad Blocks on Other Drives\n", Controller); - break; - case DAC960_V1_RebuildFailed_NewDriveFailed: - DAC960_Progress("Rebuild Failed due to " - "Failure of Drive Being Rebuilt\n", Controller); - break; - case DAC960_V1_NoRebuildOrCheckInProgress: - break; - case DAC960_V1_RebuildSuccessful: - DAC960_Progress("Rebuild Completed Successfully\n", Controller); - break; - case DAC960_V1_RebuildSuccessfullyTerminated: - DAC960_Progress("Rebuild Successfully Terminated\n", Controller); - break; - } - Controller->V1.LastRebuildStatus = CommandStatus; - if (CommandType != DAC960_MonitoringCommand && - Controller->V1.RebuildStatusPending) - { - Command->V1.CommandStatus = Controller->V1.PendingRebuildStatus; - Controller->V1.RebuildStatusPending = false; - } - else if (CommandType == DAC960_MonitoringCommand && - CommandStatus != DAC960_V1_NormalCompletion && - CommandStatus != DAC960_V1_NoRebuildOrCheckInProgress) - { - Controller->V1.PendingRebuildStatus = CommandStatus; - Controller->V1.RebuildStatusPending = true; - } - } - else if (CommandOpcode == DAC960_V1_RebuildStat) - { - unsigned int LogicalDriveNumber = - Controller->V1.RebuildProgress->LogicalDriveNumber; - unsigned int LogicalDriveSize = - Controller->V1.RebuildProgress->LogicalDriveSize; - unsigned int BlocksCompleted = - LogicalDriveSize - Controller->V1.RebuildProgress->RemainingBlocks; - if (CommandStatus == DAC960_V1_NormalCompletion) - { - Controller->EphemeralProgressMessage = true; - DAC960_Progress("Consistency Check in Progress: " - "Logical Drive %d (/dev/rd/c%dd%d) " - "%d%% completed\n", - Controller, LogicalDriveNumber, - Controller->ControllerNumber, - LogicalDriveNumber, - (100 * (BlocksCompleted >> 7)) - / (LogicalDriveSize >> 7)); - Controller->EphemeralProgressMessage = false; - } - } - else if (CommandOpcode == DAC960_V1_BackgroundInitializationControl) - { - unsigned int LogicalDriveNumber = - Controller->V1.BackgroundInitializationStatus->LogicalDriveNumber; - unsigned int LogicalDriveSize = - Controller->V1.BackgroundInitializationStatus->LogicalDriveSize; - unsigned int BlocksCompleted = - Controller->V1.BackgroundInitializationStatus->BlocksCompleted; - switch (CommandStatus) - { - case DAC960_V1_NormalCompletion: - switch (Controller->V1.BackgroundInitializationStatus->Status) - { - case DAC960_V1_BackgroundInitializationInvalid: - break; - case DAC960_V1_BackgroundInitializationStarted: - DAC960_Progress("Background Initialization Started\n", - Controller); - break; - case DAC960_V1_BackgroundInitializationInProgress: - if (BlocksCompleted == - Controller->V1.LastBackgroundInitializationStatus. - BlocksCompleted && - LogicalDriveNumber == - Controller->V1.LastBackgroundInitializationStatus. - LogicalDriveNumber) - break; - Controller->EphemeralProgressMessage = true; - DAC960_Progress("Background Initialization in Progress: " - "Logical Drive %d (/dev/rd/c%dd%d) " - "%d%% completed\n", - Controller, LogicalDriveNumber, - Controller->ControllerNumber, - LogicalDriveNumber, - (100 * (BlocksCompleted >> 7)) - / (LogicalDriveSize >> 7)); - Controller->EphemeralProgressMessage = false; - break; - case DAC960_V1_BackgroundInitializationSuspended: - DAC960_Progress("Background Initialization Suspended\n", - Controller); - break; - case DAC960_V1_BackgroundInitializationCancelled: - DAC960_Progress("Background Initialization Cancelled\n", - Controller); - break; - } - memcpy(&Controller->V1.LastBackgroundInitializationStatus, - Controller->V1.BackgroundInitializationStatus, - sizeof(DAC960_V1_BackgroundInitializationStatus_T)); - break; - case DAC960_V1_BackgroundInitSuccessful: - if (Controller->V1.BackgroundInitializationStatus->Status == - DAC960_V1_BackgroundInitializationInProgress) - DAC960_Progress("Background Initialization " - "Completed Successfully\n", Controller); - Controller->V1.BackgroundInitializationStatus->Status = - DAC960_V1_BackgroundInitializationInvalid; - break; - case DAC960_V1_BackgroundInitAborted: - if (Controller->V1.BackgroundInitializationStatus->Status == - DAC960_V1_BackgroundInitializationInProgress) - DAC960_Progress("Background Initialization Aborted\n", - Controller); - Controller->V1.BackgroundInitializationStatus->Status = - DAC960_V1_BackgroundInitializationInvalid; - break; - case DAC960_V1_NoBackgroundInitInProgress: - break; - } - } - else if (CommandOpcode == DAC960_V1_DCDB) - { - /* - This is a bit ugly. - - The InquiryStandardData and - the InquiryUntitSerialNumber information - retrieval operations BOTH use the DAC960_V1_DCDB - commands. the test above can't distinguish between - these two cases. - - Instead, we rely on the order of code later in this - function to ensure that DeviceInquiryInformation commands - are submitted before DeviceSerialNumber commands. - */ - if (Controller->V1.NeedDeviceInquiryInformation) - { - DAC960_SCSI_Inquiry_T *InquiryStandardData = - &Controller->V1.InquiryStandardData - [Controller->V1.DeviceStateChannel] - [Controller->V1.DeviceStateTargetID]; - if (CommandStatus != DAC960_V1_NormalCompletion) - { - memset(InquiryStandardData, 0, - sizeof(DAC960_SCSI_Inquiry_T)); - InquiryStandardData->PeripheralDeviceType = 0x1F; - } - else - memcpy(InquiryStandardData, - Controller->V1.NewInquiryStandardData, - sizeof(DAC960_SCSI_Inquiry_T)); - Controller->V1.NeedDeviceInquiryInformation = false; - } - else if (Controller->V1.NeedDeviceSerialNumberInformation) - { - DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber = - &Controller->V1.InquiryUnitSerialNumber - [Controller->V1.DeviceStateChannel] - [Controller->V1.DeviceStateTargetID]; - if (CommandStatus != DAC960_V1_NormalCompletion) - { - memset(InquiryUnitSerialNumber, 0, - sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T)); - InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F; - } - else - memcpy(InquiryUnitSerialNumber, - Controller->V1.NewInquiryUnitSerialNumber, - sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T)); - Controller->V1.NeedDeviceSerialNumberInformation = false; - } - } - /* - Begin submitting new monitoring commands. - */ - if (Controller->V1.NewEventLogSequenceNumber - - Controller->V1.OldEventLogSequenceNumber > 0) - { - Command->V1.CommandMailbox.Type3E.CommandOpcode = - DAC960_V1_PerformEventLogOperation; - Command->V1.CommandMailbox.Type3E.OperationType = - DAC960_V1_GetEventLogEntry; - Command->V1.CommandMailbox.Type3E.OperationQualifier = 1; - Command->V1.CommandMailbox.Type3E.SequenceNumber = - Controller->V1.OldEventLogSequenceNumber; - Command->V1.CommandMailbox.Type3E.BusAddress = - Controller->V1.EventLogEntryDMA; - DAC960_QueueCommand(Command); - return; - } - if (Controller->V1.NeedErrorTableInformation) - { - Controller->V1.NeedErrorTableInformation = false; - Command->V1.CommandMailbox.Type3.CommandOpcode = - DAC960_V1_GetErrorTable; - Command->V1.CommandMailbox.Type3.BusAddress = - Controller->V1.NewErrorTableDMA; - DAC960_QueueCommand(Command); - return; - } - if (Controller->V1.NeedRebuildProgress && - Controller->V1.RebuildProgressFirst) - { - Controller->V1.NeedRebuildProgress = false; - Command->V1.CommandMailbox.Type3.CommandOpcode = - DAC960_V1_GetRebuildProgress; - Command->V1.CommandMailbox.Type3.BusAddress = - Controller->V1.RebuildProgressDMA; - DAC960_QueueCommand(Command); - return; - } - if (Controller->V1.NeedDeviceStateInformation) - { - if (Controller->V1.NeedDeviceInquiryInformation) - { - DAC960_V1_DCDB_T *DCDB = Controller->V1.MonitoringDCDB; - dma_addr_t DCDB_DMA = Controller->V1.MonitoringDCDB_DMA; - - dma_addr_t NewInquiryStandardDataDMA = - Controller->V1.NewInquiryStandardDataDMA; - - Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB; - Command->V1.CommandMailbox.Type3.BusAddress = DCDB_DMA; - DCDB->Channel = Controller->V1.DeviceStateChannel; - DCDB->TargetID = Controller->V1.DeviceStateTargetID; - DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem; - DCDB->EarlyStatus = false; - DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds; - DCDB->NoAutomaticRequestSense = false; - DCDB->DisconnectPermitted = true; - DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T); - DCDB->BusAddress = NewInquiryStandardDataDMA; - DCDB->CDBLength = 6; - DCDB->TransferLengthHigh4 = 0; - DCDB->SenseLength = sizeof(DCDB->SenseData); - DCDB->CDB[0] = 0x12; /* INQUIRY */ - DCDB->CDB[1] = 0; /* EVPD = 0 */ - DCDB->CDB[2] = 0; /* Page Code */ - DCDB->CDB[3] = 0; /* Reserved */ - DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_T); - DCDB->CDB[5] = 0; /* Control */ - DAC960_QueueCommand(Command); - return; - } - if (Controller->V1.NeedDeviceSerialNumberInformation) - { - DAC960_V1_DCDB_T *DCDB = Controller->V1.MonitoringDCDB; - dma_addr_t DCDB_DMA = Controller->V1.MonitoringDCDB_DMA; - dma_addr_t NewInquiryUnitSerialNumberDMA = - Controller->V1.NewInquiryUnitSerialNumberDMA; - - Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB; - Command->V1.CommandMailbox.Type3.BusAddress = DCDB_DMA; - DCDB->Channel = Controller->V1.DeviceStateChannel; - DCDB->TargetID = Controller->V1.DeviceStateTargetID; - DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem; - DCDB->EarlyStatus = false; - DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds; - DCDB->NoAutomaticRequestSense = false; - DCDB->DisconnectPermitted = true; - DCDB->TransferLength = - sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T); - DCDB->BusAddress = NewInquiryUnitSerialNumberDMA; - DCDB->CDBLength = 6; - DCDB->TransferLengthHigh4 = 0; - DCDB->SenseLength = sizeof(DCDB->SenseData); - DCDB->CDB[0] = 0x12; /* INQUIRY */ - DCDB->CDB[1] = 1; /* EVPD = 1 */ - DCDB->CDB[2] = 0x80; /* Page Code */ - DCDB->CDB[3] = 0; /* Reserved */ - DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T); - DCDB->CDB[5] = 0; /* Control */ - DAC960_QueueCommand(Command); - return; - } - if (Controller->V1.StartDeviceStateScan) - { - Controller->V1.DeviceStateChannel = 0; - Controller->V1.DeviceStateTargetID = 0; - Controller->V1.StartDeviceStateScan = false; - } - else if (++Controller->V1.DeviceStateTargetID == Controller->Targets) - { - Controller->V1.DeviceStateChannel++; - Controller->V1.DeviceStateTargetID = 0; - } - if (Controller->V1.DeviceStateChannel < Controller->Channels) - { - Controller->V1.NewDeviceState->DeviceState = - DAC960_V1_Device_Dead; - Command->V1.CommandMailbox.Type3D.CommandOpcode = - DAC960_V1_GetDeviceState; - Command->V1.CommandMailbox.Type3D.Channel = - Controller->V1.DeviceStateChannel; - Command->V1.CommandMailbox.Type3D.TargetID = - Controller->V1.DeviceStateTargetID; - Command->V1.CommandMailbox.Type3D.BusAddress = - Controller->V1.NewDeviceStateDMA; - DAC960_QueueCommand(Command); - return; - } - Controller->V1.NeedDeviceStateInformation = false; - } - if (Controller->V1.NeedLogicalDriveInformation) - { - Controller->V1.NeedLogicalDriveInformation = false; - Command->V1.CommandMailbox.Type3.CommandOpcode = - DAC960_V1_GetLogicalDriveInformation; - Command->V1.CommandMailbox.Type3.BusAddress = - Controller->V1.NewLogicalDriveInformationDMA; - DAC960_QueueCommand(Command); - return; - } - if (Controller->V1.NeedRebuildProgress) - { - Controller->V1.NeedRebuildProgress = false; - Command->V1.CommandMailbox.Type3.CommandOpcode = - DAC960_V1_GetRebuildProgress; - Command->V1.CommandMailbox.Type3.BusAddress = - Controller->V1.RebuildProgressDMA; - DAC960_QueueCommand(Command); - return; - } - if (Controller->V1.NeedConsistencyCheckProgress) - { - Controller->V1.NeedConsistencyCheckProgress = false; - Command->V1.CommandMailbox.Type3.CommandOpcode = - DAC960_V1_RebuildStat; - Command->V1.CommandMailbox.Type3.BusAddress = - Controller->V1.RebuildProgressDMA; - DAC960_QueueCommand(Command); - return; - } - if (Controller->V1.NeedBackgroundInitializationStatus) - { - Controller->V1.NeedBackgroundInitializationStatus = false; - Command->V1.CommandMailbox.Type3B.CommandOpcode = - DAC960_V1_BackgroundInitializationControl; - Command->V1.CommandMailbox.Type3B.CommandOpcode2 = 0x20; - Command->V1.CommandMailbox.Type3B.BusAddress = - Controller->V1.BackgroundInitializationStatusDMA; - DAC960_QueueCommand(Command); - return; - } - Controller->MonitoringTimerCount++; - Controller->MonitoringTimer.expires = - jiffies + DAC960_MonitoringTimerInterval; - add_timer(&Controller->MonitoringTimer); - } - if (CommandType == DAC960_ImmediateCommand) - { - complete(Command->Completion); - Command->Completion = NULL; - return; - } - if (CommandType == DAC960_QueuedCommand) - { - DAC960_V1_KernelCommand_T *KernelCommand = Command->V1.KernelCommand; - KernelCommand->CommandStatus = Command->V1.CommandStatus; - Command->V1.KernelCommand = NULL; - if (CommandOpcode == DAC960_V1_DCDB) - Controller->V1.DirectCommandActive[KernelCommand->DCDB->Channel] - [KernelCommand->DCDB->TargetID] = - false; - DAC960_DeallocateCommand(Command); - KernelCommand->CompletionFunction(KernelCommand); - return; - } - /* - Queue a Status Monitoring Command to the Controller using the just - completed Command if one was deferred previously due to lack of a - free Command when the Monitoring Timer Function was called. - */ - if (Controller->MonitoringCommandDeferred) - { - Controller->MonitoringCommandDeferred = false; - DAC960_V1_QueueMonitoringCommand(Command); - return; - } - /* - Deallocate the Command. - */ - DAC960_DeallocateCommand(Command); - /* - Wake up any processes waiting on a free Command. - */ - wake_up(&Controller->CommandWaitQueue); -} - - -/* - DAC960_V2_ReadWriteError prints an appropriate error message for Command - when an error occurs on a Read or Write operation. -*/ - -static void DAC960_V2_ReadWriteError(DAC960_Command_T *Command) -{ - DAC960_Controller_T *Controller = Command->Controller; - static const unsigned char *SenseErrors[] = { - "NO SENSE", "RECOVERED ERROR", - "NOT READY", "MEDIUM ERROR", - "HARDWARE ERROR", "ILLEGAL REQUEST", - "UNIT ATTENTION", "DATA PROTECT", - "BLANK CHECK", "VENDOR-SPECIFIC", - "COPY ABORTED", "ABORTED COMMAND", - "EQUAL", "VOLUME OVERFLOW", - "MISCOMPARE", "RESERVED" - }; - unsigned char *CommandName = "UNKNOWN"; - switch (Command->CommandType) - { - case DAC960_ReadCommand: - case DAC960_ReadRetryCommand: - CommandName = "READ"; - break; - case DAC960_WriteCommand: - case DAC960_WriteRetryCommand: - CommandName = "WRITE"; - break; - case DAC960_MonitoringCommand: - case DAC960_ImmediateCommand: - case DAC960_QueuedCommand: - break; - } - DAC960_Error("Error Condition %s on %s:\n", Controller, - SenseErrors[Command->V2.RequestSense->SenseKey], CommandName); - DAC960_Error(" /dev/rd/c%dd%d: absolute blocks %u..%u\n", - Controller, Controller->ControllerNumber, - Command->LogicalDriveNumber, Command->BlockNumber, - Command->BlockNumber + Command->BlockCount - 1); -} - - -/* - DAC960_V2_ReportEvent prints an appropriate message when a Controller Event - occurs. -*/ - -static void DAC960_V2_ReportEvent(DAC960_Controller_T *Controller, - DAC960_V2_Event_T *Event) -{ - DAC960_SCSI_RequestSense_T *RequestSense = - (DAC960_SCSI_RequestSense_T *) &Event->RequestSenseData; - unsigned char MessageBuffer[DAC960_LineBufferSize]; - static struct { int EventCode; unsigned char *EventMessage; } EventList[] = - { /* Physical Device Events (0x0000 - 0x007F) */ - { 0x0001, "P Online" }, - { 0x0002, "P Standby" }, - { 0x0005, "P Automatic Rebuild Started" }, - { 0x0006, "P Manual Rebuild Started" }, - { 0x0007, "P Rebuild Completed" }, - { 0x0008, "P Rebuild Cancelled" }, - { 0x0009, "P Rebuild Failed for Unknown Reasons" }, - { 0x000A, "P Rebuild Failed due to New Physical Device" }, - { 0x000B, "P Rebuild Failed due to Logical Drive Failure" }, - { 0x000C, "S Offline" }, - { 0x000D, "P Found" }, - { 0x000E, "P Removed" }, - { 0x000F, "P Unconfigured" }, - { 0x0010, "P Expand Capacity Started" }, - { 0x0011, "P Expand Capacity Completed" }, - { 0x0012, "P Expand Capacity Failed" }, - { 0x0013, "P Command Timed Out" }, - { 0x0014, "P Command Aborted" }, - { 0x0015, "P Command Retried" }, - { 0x0016, "P Parity Error" }, - { 0x0017, "P Soft Error" }, - { 0x0018, "P Miscellaneous Error" }, - { 0x0019, "P Reset" }, - { 0x001A, "P Active Spare Found" }, - { 0x001B, "P Warm Spare Found" }, - { 0x001C, "S Sense Data Received" }, - { 0x001D, "P Initialization Started" }, - { 0x001E, "P Initialization Completed" }, - { 0x001F, "P Initialization Failed" }, - { 0x0020, "P Initialization Cancelled" }, - { 0x0021, "P Failed because Write Recovery Failed" }, - { 0x0022, "P Failed because SCSI Bus Reset Failed" }, - { 0x0023, "P Failed because of Double Check Condition" }, - { 0x0024, "P Failed because Device Cannot Be Accessed" }, - { 0x0025, "P Failed because of Gross Error on SCSI Processor" }, - { 0x0026, "P Failed because of Bad Tag from Device" }, - { 0x0027, "P Failed because of Command Timeout" }, - { 0x0028, "P Failed because of System Reset" }, - { 0x0029, "P Failed because of Busy Status or Parity Error" }, - { 0x002A, "P Failed because Host Set Device to Failed State" }, - { 0x002B, "P Failed because of Selection Timeout" }, - { 0x002C, "P Failed because of SCSI Bus Phase Error" }, - { 0x002D, "P Failed because Device Returned Unknown Status" }, - { 0x002E, "P Failed because Device Not Ready" }, - { 0x002F, "P Failed because Device Not Found at Startup" }, - { 0x0030, "P Failed because COD Write Operation Failed" }, - { 0x0031, "P Failed because BDT Write Operation Failed" }, - { 0x0039, "P Missing at Startup" }, - { 0x003A, "P Start Rebuild Failed due to Physical Drive Too Small" }, - { 0x003C, "P Temporarily Offline Device Automatically Made Online" }, - { 0x003D, "P Standby Rebuild Started" }, - /* Logical Device Events (0x0080 - 0x00FF) */ - { 0x0080, "M Consistency Check Started" }, - { 0x0081, "M Consistency Check Completed" }, - { 0x0082, "M Consistency Check Cancelled" }, - { 0x0083, "M Consistency Check Completed With Errors" }, - { 0x0084, "M Consistency Check Failed due to Logical Drive Failure" }, - { 0x0085, "M Consistency Check Failed due to Physical Device Failure" }, - { 0x0086, "L Offline" }, - { 0x0087, "L Critical" }, - { 0x0088, "L Online" }, - { 0x0089, "M Automatic Rebuild Started" }, - { 0x008A, "M Manual Rebuild Started" }, - { 0x008B, "M Rebuild Completed" }, - { 0x008C, "M Rebuild Cancelled" }, - { 0x008D, "M Rebuild Failed for Unknown Reasons" }, - { 0x008E, "M Rebuild Failed due to New Physical Device" }, - { 0x008F, "M Rebuild Failed due to Logical Drive Failure" }, - { 0x0090, "M Initialization Started" }, - { 0x0091, "M Initialization Completed" }, - { 0x0092, "M Initialization Cancelled" }, - { 0x0093, "M Initialization Failed" }, - { 0x0094, "L Found" }, - { 0x0095, "L Deleted" }, - { 0x0096, "M Expand Capacity Started" }, - { 0x0097, "M Expand Capacity Completed" }, - { 0x0098, "M Expand Capacity Failed" }, - { 0x0099, "L Bad Block Found" }, - { 0x009A, "L Size Changed" }, - { 0x009B, "L Type Changed" }, - { 0x009C, "L Bad Data Block Found" }, - { 0x009E, "L Read of Data Block in BDT" }, - { 0x009F, "L Write Back Data for Disk Block Lost" }, - { 0x00A0, "L Temporarily Offline RAID-5/3 Drive Made Online" }, - { 0x00A1, "L Temporarily Offline RAID-6/1/0/7 Drive Made Online" }, - { 0x00A2, "L Standby Rebuild Started" }, - /* Fault Management Events (0x0100 - 0x017F) */ - { 0x0140, "E Fan %d Failed" }, - { 0x0141, "E Fan %d OK" }, - { 0x0142, "E Fan %d Not Present" }, - { 0x0143, "E Power Supply %d Failed" }, - { 0x0144, "E Power Supply %d OK" }, - { 0x0145, "E Power Supply %d Not Present" }, - { 0x0146, "E Temperature Sensor %d Temperature Exceeds Safe Limit" }, - { 0x0147, "E Temperature Sensor %d Temperature Exceeds Working Limit" }, - { 0x0148, "E Temperature Sensor %d Temperature Normal" }, - { 0x0149, "E Temperature Sensor %d Not Present" }, - { 0x014A, "E Enclosure Management Unit %d Access Critical" }, - { 0x014B, "E Enclosure Management Unit %d Access OK" }, - { 0x014C, "E Enclosure Management Unit %d Access Offline" }, - /* Controller Events (0x0180 - 0x01FF) */ - { 0x0181, "C Cache Write Back Error" }, - { 0x0188, "C Battery Backup Unit Found" }, - { 0x0189, "C Battery Backup Unit Charge Level Low" }, - { 0x018A, "C Battery Backup Unit Charge Level OK" }, - { 0x0193, "C Installation Aborted" }, - { 0x0195, "C Battery Backup Unit Physically Removed" }, - { 0x0196, "C Memory Error During Warm Boot" }, - { 0x019E, "C Memory Soft ECC Error Corrected" }, - { 0x019F, "C Memory Hard ECC Error Corrected" }, - { 0x01A2, "C Battery Backup Unit Failed" }, - { 0x01AB, "C Mirror Race Recovery Failed" }, - { 0x01AC, "C Mirror Race on Critical Drive" }, - /* Controller Internal Processor Events */ - { 0x0380, "C Internal Controller Hung" }, - { 0x0381, "C Internal Controller Firmware Breakpoint" }, - { 0x0390, "C Internal Controller i960 Processor Specific Error" }, - { 0x03A0, "C Internal Controller StrongARM Processor Specific Error" }, - { 0, "" } }; - int EventListIndex = 0, EventCode; - unsigned char EventType, *EventMessage; - if (Event->EventCode == 0x1C && - RequestSense->SenseKey == DAC960_SenseKey_VendorSpecific && - (RequestSense->AdditionalSenseCode == 0x80 || - RequestSense->AdditionalSenseCode == 0x81)) - Event->EventCode = ((RequestSense->AdditionalSenseCode - 0x80) << 8) | - RequestSense->AdditionalSenseCodeQualifier; - while (true) - { - EventCode = EventList[EventListIndex].EventCode; - if (EventCode == Event->EventCode || EventCode == 0) break; - EventListIndex++; - } - EventType = EventList[EventListIndex].EventMessage[0]; - EventMessage = &EventList[EventListIndex].EventMessage[2]; - if (EventCode == 0) - { - DAC960_Critical("Unknown Controller Event Code %04X\n", - Controller, Event->EventCode); - return; - } - switch (EventType) - { - case 'P': - DAC960_Critical("Physical Device %d:%d %s\n", Controller, - Event->Channel, Event->TargetID, EventMessage); - break; - case 'L': - DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) %s\n", Controller, - Event->LogicalUnit, Controller->ControllerNumber, - Event->LogicalUnit, EventMessage); - break; - case 'M': - DAC960_Progress("Logical Drive %d (/dev/rd/c%dd%d) %s\n", Controller, - Event->LogicalUnit, Controller->ControllerNumber, - Event->LogicalUnit, EventMessage); - break; - case 'S': - if (RequestSense->SenseKey == DAC960_SenseKey_NoSense || - (RequestSense->SenseKey == DAC960_SenseKey_NotReady && - RequestSense->AdditionalSenseCode == 0x04 && - (RequestSense->AdditionalSenseCodeQualifier == 0x01 || - RequestSense->AdditionalSenseCodeQualifier == 0x02))) - break; - DAC960_Critical("Physical Device %d:%d %s\n", Controller, - Event->Channel, Event->TargetID, EventMessage); - DAC960_Critical("Physical Device %d:%d Request Sense: " - "Sense Key = %X, ASC = %02X, ASCQ = %02X\n", - Controller, - Event->Channel, - Event->TargetID, - RequestSense->SenseKey, - RequestSense->AdditionalSenseCode, - RequestSense->AdditionalSenseCodeQualifier); - DAC960_Critical("Physical Device %d:%d Request Sense: " - "Information = %02X%02X%02X%02X " - "%02X%02X%02X%02X\n", - Controller, - Event->Channel, - Event->TargetID, - RequestSense->Information[0], - RequestSense->Information[1], - RequestSense->Information[2], - RequestSense->Information[3], - RequestSense->CommandSpecificInformation[0], - RequestSense->CommandSpecificInformation[1], - RequestSense->CommandSpecificInformation[2], - RequestSense->CommandSpecificInformation[3]); - break; - case 'E': - if (Controller->SuppressEnclosureMessages) break; - sprintf(MessageBuffer, EventMessage, Event->LogicalUnit); - DAC960_Critical("Enclosure %d %s\n", Controller, - Event->TargetID, MessageBuffer); - break; - case 'C': - DAC960_Critical("Controller %s\n", Controller, EventMessage); - break; - default: - DAC960_Critical("Unknown Controller Event Code %04X\n", - Controller, Event->EventCode); - break; - } -} - - -/* - DAC960_V2_ReportProgress prints an appropriate progress message for - Logical Device Long Operations. -*/ - -static void DAC960_V2_ReportProgress(DAC960_Controller_T *Controller, - unsigned char *MessageString, - unsigned int LogicalDeviceNumber, - unsigned long BlocksCompleted, - unsigned long LogicalDeviceSize) -{ - Controller->EphemeralProgressMessage = true; - DAC960_Progress("%s in Progress: Logical Drive %d (/dev/rd/c%dd%d) " - "%d%% completed\n", Controller, - MessageString, - LogicalDeviceNumber, - Controller->ControllerNumber, - LogicalDeviceNumber, - (100 * (BlocksCompleted >> 7)) / (LogicalDeviceSize >> 7)); - Controller->EphemeralProgressMessage = false; -} - - -/* - DAC960_V2_ProcessCompletedCommand performs completion processing for Command - for DAC960 V2 Firmware Controllers. -*/ - -static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) -{ - DAC960_Controller_T *Controller = Command->Controller; - DAC960_CommandType_T CommandType = Command->CommandType; - DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; - DAC960_V2_IOCTL_Opcode_T IOCTLOpcode = CommandMailbox->Common.IOCTL_Opcode; - DAC960_V2_CommandOpcode_T CommandOpcode = CommandMailbox->SCSI_10.CommandOpcode; - DAC960_V2_CommandStatus_T CommandStatus = Command->V2.CommandStatus; - - if (CommandType == DAC960_ReadCommand || - CommandType == DAC960_WriteCommand) - { - -#ifdef FORCE_RETRY_DEBUG - CommandStatus = DAC960_V2_AbormalCompletion; -#endif - Command->V2.RequestSense->SenseKey = DAC960_SenseKey_MediumError; - - if (CommandStatus == DAC960_V2_NormalCompletion) { - - if (!DAC960_ProcessCompletedRequest(Command, true)) - BUG(); - - } else if (Command->V2.RequestSense->SenseKey == DAC960_SenseKey_MediumError) - { - /* - * break the command down into pieces and resubmit each - * piece, hoping that some of them will succeed. - */ - DAC960_queue_partial_rw(Command); - return; - } - else - { - if (Command->V2.RequestSense->SenseKey != DAC960_SenseKey_NotReady) - DAC960_V2_ReadWriteError(Command); - /* - Perform completion processing for all buffers in this I/O Request. - */ - (void)DAC960_ProcessCompletedRequest(Command, false); - } - } - else if (CommandType == DAC960_ReadRetryCommand || - CommandType == DAC960_WriteRetryCommand) - { - bool normal_completion; - -#ifdef FORCE_RETRY_FAILURE_DEBUG - static int retry_count = 1; -#endif - /* - Perform completion processing for the portion that was - retried, and submit the next portion, if any. - */ - normal_completion = true; - if (CommandStatus != DAC960_V2_NormalCompletion) { - normal_completion = false; - if (Command->V2.RequestSense->SenseKey != DAC960_SenseKey_NotReady) - DAC960_V2_ReadWriteError(Command); - } - -#ifdef FORCE_RETRY_FAILURE_DEBUG - if (!(++retry_count % 10000)) { - printk("V2 error retry failure test\n"); - normal_completion = false; - DAC960_V2_ReadWriteError(Command); - } -#endif - - if (!DAC960_ProcessCompletedRequest(Command, normal_completion)) { - DAC960_queue_partial_rw(Command); - return; - } - } - else if (CommandType == DAC960_MonitoringCommand) - { - if (Controller->ShutdownMonitoringTimer) - return; - if (IOCTLOpcode == DAC960_V2_GetControllerInfo) - { - DAC960_V2_ControllerInfo_T *NewControllerInfo = - Controller->V2.NewControllerInformation; - DAC960_V2_ControllerInfo_T *ControllerInfo = - &Controller->V2.ControllerInformation; - Controller->LogicalDriveCount = - NewControllerInfo->LogicalDevicesPresent; - Controller->V2.NeedLogicalDeviceInformation = true; - Controller->V2.NeedPhysicalDeviceInformation = true; - Controller->V2.StartLogicalDeviceInformationScan = true; - Controller->V2.StartPhysicalDeviceInformationScan = true; - Controller->MonitoringAlertMode = - (NewControllerInfo->LogicalDevicesCritical > 0 || - NewControllerInfo->LogicalDevicesOffline > 0 || - NewControllerInfo->PhysicalDisksCritical > 0 || - NewControllerInfo->PhysicalDisksOffline > 0); - memcpy(ControllerInfo, NewControllerInfo, - sizeof(DAC960_V2_ControllerInfo_T)); - } - else if (IOCTLOpcode == DAC960_V2_GetEvent) - { - if (CommandStatus == DAC960_V2_NormalCompletion) { - DAC960_V2_ReportEvent(Controller, Controller->V2.Event); - } - Controller->V2.NextEventSequenceNumber++; - } - else if (IOCTLOpcode == DAC960_V2_GetPhysicalDeviceInfoValid && - CommandStatus == DAC960_V2_NormalCompletion) - { - DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo = - Controller->V2.NewPhysicalDeviceInformation; - unsigned int PhysicalDeviceIndex = Controller->V2.PhysicalDeviceIndex; - DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo = - Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex]; - DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber = - Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex]; - unsigned int DeviceIndex; - while (PhysicalDeviceInfo != NULL && - (NewPhysicalDeviceInfo->Channel > - PhysicalDeviceInfo->Channel || - (NewPhysicalDeviceInfo->Channel == - PhysicalDeviceInfo->Channel && - (NewPhysicalDeviceInfo->TargetID > - PhysicalDeviceInfo->TargetID || - (NewPhysicalDeviceInfo->TargetID == - PhysicalDeviceInfo->TargetID && - NewPhysicalDeviceInfo->LogicalUnit > - PhysicalDeviceInfo->LogicalUnit))))) - { - DAC960_Critical("Physical Device %d:%d No Longer Exists\n", - Controller, - PhysicalDeviceInfo->Channel, - PhysicalDeviceInfo->TargetID); - Controller->V2.PhysicalDeviceInformation - [PhysicalDeviceIndex] = NULL; - Controller->V2.InquiryUnitSerialNumber - [PhysicalDeviceIndex] = NULL; - kfree(PhysicalDeviceInfo); - kfree(InquiryUnitSerialNumber); - for (DeviceIndex = PhysicalDeviceIndex; - DeviceIndex < DAC960_V2_MaxPhysicalDevices - 1; - DeviceIndex++) - { - Controller->V2.PhysicalDeviceInformation[DeviceIndex] = - Controller->V2.PhysicalDeviceInformation[DeviceIndex+1]; - Controller->V2.InquiryUnitSerialNumber[DeviceIndex] = - Controller->V2.InquiryUnitSerialNumber[DeviceIndex+1]; - } - Controller->V2.PhysicalDeviceInformation - [DAC960_V2_MaxPhysicalDevices-1] = NULL; - Controller->V2.InquiryUnitSerialNumber - [DAC960_V2_MaxPhysicalDevices-1] = NULL; - PhysicalDeviceInfo = - Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex]; - InquiryUnitSerialNumber = - Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex]; - } - if (PhysicalDeviceInfo == NULL || - (NewPhysicalDeviceInfo->Channel != - PhysicalDeviceInfo->Channel) || - (NewPhysicalDeviceInfo->TargetID != - PhysicalDeviceInfo->TargetID) || - (NewPhysicalDeviceInfo->LogicalUnit != - PhysicalDeviceInfo->LogicalUnit)) - { - PhysicalDeviceInfo = - kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC); - InquiryUnitSerialNumber = - kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), - GFP_ATOMIC); - if (InquiryUnitSerialNumber == NULL || - PhysicalDeviceInfo == NULL) - { - kfree(InquiryUnitSerialNumber); - InquiryUnitSerialNumber = NULL; - kfree(PhysicalDeviceInfo); - PhysicalDeviceInfo = NULL; - } - DAC960_Critical("Physical Device %d:%d Now Exists%s\n", - Controller, - NewPhysicalDeviceInfo->Channel, - NewPhysicalDeviceInfo->TargetID, - (PhysicalDeviceInfo != NULL - ? "" : " - Allocation Failed")); - if (PhysicalDeviceInfo != NULL) - { - memset(PhysicalDeviceInfo, 0, - sizeof(DAC960_V2_PhysicalDeviceInfo_T)); - PhysicalDeviceInfo->PhysicalDeviceState = - DAC960_V2_Device_InvalidState; - memset(InquiryUnitSerialNumber, 0, - sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T)); - InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F; - for (DeviceIndex = DAC960_V2_MaxPhysicalDevices - 1; - DeviceIndex > PhysicalDeviceIndex; - DeviceIndex--) - { - Controller->V2.PhysicalDeviceInformation[DeviceIndex] = - Controller->V2.PhysicalDeviceInformation[DeviceIndex-1]; - Controller->V2.InquiryUnitSerialNumber[DeviceIndex] = - Controller->V2.InquiryUnitSerialNumber[DeviceIndex-1]; - } - Controller->V2.PhysicalDeviceInformation - [PhysicalDeviceIndex] = - PhysicalDeviceInfo; - Controller->V2.InquiryUnitSerialNumber - [PhysicalDeviceIndex] = - InquiryUnitSerialNumber; - Controller->V2.NeedDeviceSerialNumberInformation = true; - } - } - if (PhysicalDeviceInfo != NULL) - { - if (NewPhysicalDeviceInfo->PhysicalDeviceState != - PhysicalDeviceInfo->PhysicalDeviceState) - DAC960_Critical( - "Physical Device %d:%d is now %s\n", Controller, - NewPhysicalDeviceInfo->Channel, - NewPhysicalDeviceInfo->TargetID, - (NewPhysicalDeviceInfo->PhysicalDeviceState - == DAC960_V2_Device_Online - ? "ONLINE" - : NewPhysicalDeviceInfo->PhysicalDeviceState - == DAC960_V2_Device_Rebuild - ? "REBUILD" - : NewPhysicalDeviceInfo->PhysicalDeviceState - == DAC960_V2_Device_Missing - ? "MISSING" - : NewPhysicalDeviceInfo->PhysicalDeviceState - == DAC960_V2_Device_Critical - ? "CRITICAL" - : NewPhysicalDeviceInfo->PhysicalDeviceState - == DAC960_V2_Device_Dead - ? "DEAD" - : NewPhysicalDeviceInfo->PhysicalDeviceState - == DAC960_V2_Device_SuspectedDead - ? "SUSPECTED-DEAD" - : NewPhysicalDeviceInfo->PhysicalDeviceState - == DAC960_V2_Device_CommandedOffline - ? "COMMANDED-OFFLINE" - : NewPhysicalDeviceInfo->PhysicalDeviceState - == DAC960_V2_Device_Standby - ? "STANDBY" : "UNKNOWN")); - if ((NewPhysicalDeviceInfo->ParityErrors != - PhysicalDeviceInfo->ParityErrors) || - (NewPhysicalDeviceInfo->SoftErrors != - PhysicalDeviceInfo->SoftErrors) || - (NewPhysicalDeviceInfo->HardErrors != - PhysicalDeviceInfo->HardErrors) || - (NewPhysicalDeviceInfo->MiscellaneousErrors != - PhysicalDeviceInfo->MiscellaneousErrors) || - (NewPhysicalDeviceInfo->CommandTimeouts != - PhysicalDeviceInfo->CommandTimeouts) || - (NewPhysicalDeviceInfo->Retries != - PhysicalDeviceInfo->Retries) || - (NewPhysicalDeviceInfo->Aborts != - PhysicalDeviceInfo->Aborts) || - (NewPhysicalDeviceInfo->PredictedFailuresDetected != - PhysicalDeviceInfo->PredictedFailuresDetected)) - { - DAC960_Critical("Physical Device %d:%d Errors: " - "Parity = %d, Soft = %d, " - "Hard = %d, Misc = %d\n", - Controller, - NewPhysicalDeviceInfo->Channel, - NewPhysicalDeviceInfo->TargetID, - NewPhysicalDeviceInfo->ParityErrors, - NewPhysicalDeviceInfo->SoftErrors, - NewPhysicalDeviceInfo->HardErrors, - NewPhysicalDeviceInfo->MiscellaneousErrors); - DAC960_Critical("Physical Device %d:%d Errors: " - "Timeouts = %d, Retries = %d, " - "Aborts = %d, Predicted = %d\n", - Controller, - NewPhysicalDeviceInfo->Channel, - NewPhysicalDeviceInfo->TargetID, - NewPhysicalDeviceInfo->CommandTimeouts, - NewPhysicalDeviceInfo->Retries, - NewPhysicalDeviceInfo->Aborts, - NewPhysicalDeviceInfo - ->PredictedFailuresDetected); - } - if ((PhysicalDeviceInfo->PhysicalDeviceState - == DAC960_V2_Device_Dead || - PhysicalDeviceInfo->PhysicalDeviceState - == DAC960_V2_Device_InvalidState) && - NewPhysicalDeviceInfo->PhysicalDeviceState - != DAC960_V2_Device_Dead) - Controller->V2.NeedDeviceSerialNumberInformation = true; - memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo, - sizeof(DAC960_V2_PhysicalDeviceInfo_T)); - } - NewPhysicalDeviceInfo->LogicalUnit++; - Controller->V2.PhysicalDeviceIndex++; - } - else if (IOCTLOpcode == DAC960_V2_GetPhysicalDeviceInfoValid) - { - unsigned int DeviceIndex; - for (DeviceIndex = Controller->V2.PhysicalDeviceIndex; - DeviceIndex < DAC960_V2_MaxPhysicalDevices; - DeviceIndex++) - { - DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo = - Controller->V2.PhysicalDeviceInformation[DeviceIndex]; - DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber = - Controller->V2.InquiryUnitSerialNumber[DeviceIndex]; - if (PhysicalDeviceInfo == NULL) break; - DAC960_Critical("Physical Device %d:%d No Longer Exists\n", - Controller, - PhysicalDeviceInfo->Channel, - PhysicalDeviceInfo->TargetID); - Controller->V2.PhysicalDeviceInformation[DeviceIndex] = NULL; - Controller->V2.InquiryUnitSerialNumber[DeviceIndex] = NULL; - kfree(PhysicalDeviceInfo); - kfree(InquiryUnitSerialNumber); - } - Controller->V2.NeedPhysicalDeviceInformation = false; - } - else if (IOCTLOpcode == DAC960_V2_GetLogicalDeviceInfoValid && - CommandStatus == DAC960_V2_NormalCompletion) - { - DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo = - Controller->V2.NewLogicalDeviceInformation; - unsigned short LogicalDeviceNumber = - NewLogicalDeviceInfo->LogicalDeviceNumber; - DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo = - Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber]; - if (LogicalDeviceInfo == NULL) - { - DAC960_V2_PhysicalDevice_T PhysicalDevice; - PhysicalDevice.Controller = 0; - PhysicalDevice.Channel = NewLogicalDeviceInfo->Channel; - PhysicalDevice.TargetID = NewLogicalDeviceInfo->TargetID; - PhysicalDevice.LogicalUnit = NewLogicalDeviceInfo->LogicalUnit; - Controller->V2.LogicalDriveToVirtualDevice[LogicalDeviceNumber] = - PhysicalDevice; - LogicalDeviceInfo = kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), - GFP_ATOMIC); - Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] = - LogicalDeviceInfo; - DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) " - "Now Exists%s\n", Controller, - LogicalDeviceNumber, - Controller->ControllerNumber, - LogicalDeviceNumber, - (LogicalDeviceInfo != NULL - ? "" : " - Allocation Failed")); - if (LogicalDeviceInfo != NULL) - { - memset(LogicalDeviceInfo, 0, - sizeof(DAC960_V2_LogicalDeviceInfo_T)); - DAC960_ComputeGenericDiskInfo(Controller); - } - } - if (LogicalDeviceInfo != NULL) - { - unsigned long LogicalDeviceSize = - NewLogicalDeviceInfo->ConfigurableDeviceSize; - if (NewLogicalDeviceInfo->LogicalDeviceState != - LogicalDeviceInfo->LogicalDeviceState) - DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) " - "is now %s\n", Controller, - LogicalDeviceNumber, - Controller->ControllerNumber, - LogicalDeviceNumber, - (NewLogicalDeviceInfo->LogicalDeviceState - == DAC960_V2_LogicalDevice_Online - ? "ONLINE" - : NewLogicalDeviceInfo->LogicalDeviceState - == DAC960_V2_LogicalDevice_Critical - ? "CRITICAL" : "OFFLINE")); - if ((NewLogicalDeviceInfo->SoftErrors != - LogicalDeviceInfo->SoftErrors) || - (NewLogicalDeviceInfo->CommandsFailed != - LogicalDeviceInfo->CommandsFailed) || - (NewLogicalDeviceInfo->DeferredWriteErrors != - LogicalDeviceInfo->DeferredWriteErrors)) - DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) Errors: " - "Soft = %d, Failed = %d, Deferred Write = %d\n", - Controller, LogicalDeviceNumber, - Controller->ControllerNumber, - LogicalDeviceNumber, - NewLogicalDeviceInfo->SoftErrors, - NewLogicalDeviceInfo->CommandsFailed, - NewLogicalDeviceInfo->DeferredWriteErrors); - if (NewLogicalDeviceInfo->ConsistencyCheckInProgress) - DAC960_V2_ReportProgress(Controller, - "Consistency Check", - LogicalDeviceNumber, - NewLogicalDeviceInfo - ->ConsistencyCheckBlockNumber, - LogicalDeviceSize); - else if (NewLogicalDeviceInfo->RebuildInProgress) - DAC960_V2_ReportProgress(Controller, - "Rebuild", - LogicalDeviceNumber, - NewLogicalDeviceInfo - ->RebuildBlockNumber, - LogicalDeviceSize); - else if (NewLogicalDeviceInfo->BackgroundInitializationInProgress) - DAC960_V2_ReportProgress(Controller, - "Background Initialization", - LogicalDeviceNumber, - NewLogicalDeviceInfo - ->BackgroundInitializationBlockNumber, - LogicalDeviceSize); - else if (NewLogicalDeviceInfo->ForegroundInitializationInProgress) - DAC960_V2_ReportProgress(Controller, - "Foreground Initialization", - LogicalDeviceNumber, - NewLogicalDeviceInfo - ->ForegroundInitializationBlockNumber, - LogicalDeviceSize); - else if (NewLogicalDeviceInfo->DataMigrationInProgress) - DAC960_V2_ReportProgress(Controller, - "Data Migration", - LogicalDeviceNumber, - NewLogicalDeviceInfo - ->DataMigrationBlockNumber, - LogicalDeviceSize); - else if (NewLogicalDeviceInfo->PatrolOperationInProgress) - DAC960_V2_ReportProgress(Controller, - "Patrol Operation", - LogicalDeviceNumber, - NewLogicalDeviceInfo - ->PatrolOperationBlockNumber, - LogicalDeviceSize); - if (LogicalDeviceInfo->BackgroundInitializationInProgress && - !NewLogicalDeviceInfo->BackgroundInitializationInProgress) - DAC960_Progress("Logical Drive %d (/dev/rd/c%dd%d) " - "Background Initialization %s\n", - Controller, - LogicalDeviceNumber, - Controller->ControllerNumber, - LogicalDeviceNumber, - (NewLogicalDeviceInfo->LogicalDeviceControl - .LogicalDeviceInitialized - ? "Completed" : "Failed")); - memcpy(LogicalDeviceInfo, NewLogicalDeviceInfo, - sizeof(DAC960_V2_LogicalDeviceInfo_T)); - } - Controller->V2.LogicalDriveFoundDuringScan - [LogicalDeviceNumber] = true; - NewLogicalDeviceInfo->LogicalDeviceNumber++; - } - else if (IOCTLOpcode == DAC960_V2_GetLogicalDeviceInfoValid) - { - int LogicalDriveNumber; - for (LogicalDriveNumber = 0; - LogicalDriveNumber < DAC960_MaxLogicalDrives; - LogicalDriveNumber++) - { - DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo = - Controller->V2.LogicalDeviceInformation[LogicalDriveNumber]; - if (LogicalDeviceInfo == NULL || - Controller->V2.LogicalDriveFoundDuringScan - [LogicalDriveNumber]) - continue; - DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) " - "No Longer Exists\n", Controller, - LogicalDriveNumber, - Controller->ControllerNumber, - LogicalDriveNumber); - Controller->V2.LogicalDeviceInformation - [LogicalDriveNumber] = NULL; - kfree(LogicalDeviceInfo); - Controller->LogicalDriveInitiallyAccessible - [LogicalDriveNumber] = false; - DAC960_ComputeGenericDiskInfo(Controller); - } - Controller->V2.NeedLogicalDeviceInformation = false; - } - else if (CommandOpcode == DAC960_V2_SCSI_10_Passthru) - { - DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber = - Controller->V2.InquiryUnitSerialNumber[Controller->V2.PhysicalDeviceIndex - 1]; - - if (CommandStatus != DAC960_V2_NormalCompletion) { - memset(InquiryUnitSerialNumber, - 0, sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T)); - InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F; - } else - memcpy(InquiryUnitSerialNumber, - Controller->V2.NewInquiryUnitSerialNumber, - sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T)); - - Controller->V2.NeedDeviceSerialNumberInformation = false; - } - - if (Controller->V2.HealthStatusBuffer->NextEventSequenceNumber - - Controller->V2.NextEventSequenceNumber > 0) - { - CommandMailbox->GetEvent.CommandOpcode = DAC960_V2_IOCTL; - CommandMailbox->GetEvent.DataTransferSize = sizeof(DAC960_V2_Event_T); - CommandMailbox->GetEvent.EventSequenceNumberHigh16 = - Controller->V2.NextEventSequenceNumber >> 16; - CommandMailbox->GetEvent.ControllerNumber = 0; - CommandMailbox->GetEvent.IOCTL_Opcode = - DAC960_V2_GetEvent; - CommandMailbox->GetEvent.EventSequenceNumberLow16 = - Controller->V2.NextEventSequenceNumber & 0xFFFF; - CommandMailbox->GetEvent.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentDataPointer = - Controller->V2.EventDMA; - CommandMailbox->GetEvent.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentByteCount = - CommandMailbox->GetEvent.DataTransferSize; - DAC960_QueueCommand(Command); - return; - } - if (Controller->V2.NeedPhysicalDeviceInformation) - { - if (Controller->V2.NeedDeviceSerialNumberInformation) - { - DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber = - Controller->V2.NewInquiryUnitSerialNumber; - InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F; - - DAC960_V2_ConstructNewUnitSerialNumber(Controller, CommandMailbox, - Controller->V2.NewPhysicalDeviceInformation->Channel, - Controller->V2.NewPhysicalDeviceInformation->TargetID, - Controller->V2.NewPhysicalDeviceInformation->LogicalUnit - 1); - - - DAC960_QueueCommand(Command); - return; - } - if (Controller->V2.StartPhysicalDeviceInformationScan) - { - Controller->V2.PhysicalDeviceIndex = 0; - Controller->V2.NewPhysicalDeviceInformation->Channel = 0; - Controller->V2.NewPhysicalDeviceInformation->TargetID = 0; - Controller->V2.NewPhysicalDeviceInformation->LogicalUnit = 0; - Controller->V2.StartPhysicalDeviceInformationScan = false; - } - CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL; - CommandMailbox->PhysicalDeviceInfo.DataTransferSize = - sizeof(DAC960_V2_PhysicalDeviceInfo_T); - CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.LogicalUnit = - Controller->V2.NewPhysicalDeviceInformation->LogicalUnit; - CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID = - Controller->V2.NewPhysicalDeviceInformation->TargetID; - CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel = - Controller->V2.NewPhysicalDeviceInformation->Channel; - CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode = - DAC960_V2_GetPhysicalDeviceInfoValid; - CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentDataPointer = - Controller->V2.NewPhysicalDeviceInformationDMA; - CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentByteCount = - CommandMailbox->PhysicalDeviceInfo.DataTransferSize; - DAC960_QueueCommand(Command); - return; - } - if (Controller->V2.NeedLogicalDeviceInformation) - { - if (Controller->V2.StartLogicalDeviceInformationScan) - { - int LogicalDriveNumber; - for (LogicalDriveNumber = 0; - LogicalDriveNumber < DAC960_MaxLogicalDrives; - LogicalDriveNumber++) - Controller->V2.LogicalDriveFoundDuringScan - [LogicalDriveNumber] = false; - Controller->V2.NewLogicalDeviceInformation->LogicalDeviceNumber = 0; - Controller->V2.StartLogicalDeviceInformationScan = false; - } - CommandMailbox->LogicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL; - CommandMailbox->LogicalDeviceInfo.DataTransferSize = - sizeof(DAC960_V2_LogicalDeviceInfo_T); - CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber = - Controller->V2.NewLogicalDeviceInformation->LogicalDeviceNumber; - CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode = - DAC960_V2_GetLogicalDeviceInfoValid; - CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentDataPointer = - Controller->V2.NewLogicalDeviceInformationDMA; - CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentByteCount = - CommandMailbox->LogicalDeviceInfo.DataTransferSize; - DAC960_QueueCommand(Command); - return; - } - Controller->MonitoringTimerCount++; - Controller->MonitoringTimer.expires = - jiffies + DAC960_HealthStatusMonitoringInterval; - add_timer(&Controller->MonitoringTimer); - } - if (CommandType == DAC960_ImmediateCommand) - { - complete(Command->Completion); - Command->Completion = NULL; - return; - } - if (CommandType == DAC960_QueuedCommand) - { - DAC960_V2_KernelCommand_T *KernelCommand = Command->V2.KernelCommand; - KernelCommand->CommandStatus = CommandStatus; - KernelCommand->RequestSenseLength = Command->V2.RequestSenseLength; - KernelCommand->DataTransferLength = Command->V2.DataTransferResidue; - Command->V2.KernelCommand = NULL; - DAC960_DeallocateCommand(Command); - KernelCommand->CompletionFunction(KernelCommand); - return; - } - /* - Queue a Status Monitoring Command to the Controller using the just - completed Command if one was deferred previously due to lack of a - free Command when the Monitoring Timer Function was called. - */ - if (Controller->MonitoringCommandDeferred) - { - Controller->MonitoringCommandDeferred = false; - DAC960_V2_QueueMonitoringCommand(Command); - return; - } - /* - Deallocate the Command. - */ - DAC960_DeallocateCommand(Command); - /* - Wake up any processes waiting on a free Command. - */ - wake_up(&Controller->CommandWaitQueue); -} - -/* - DAC960_GEM_InterruptHandler handles hardware interrupts from DAC960 GEM Series - Controllers. -*/ - -static irqreturn_t DAC960_GEM_InterruptHandler(int IRQ_Channel, - void *DeviceIdentifier) -{ - DAC960_Controller_T *Controller = DeviceIdentifier; - void __iomem *ControllerBaseAddress = Controller->BaseAddress; - DAC960_V2_StatusMailbox_T *NextStatusMailbox; - unsigned long flags; - - spin_lock_irqsave(&Controller->queue_lock, flags); - DAC960_GEM_AcknowledgeInterrupt(ControllerBaseAddress); - NextStatusMailbox = Controller->V2.NextStatusMailbox; - while (NextStatusMailbox->Fields.CommandIdentifier > 0) - { - DAC960_V2_CommandIdentifier_T CommandIdentifier = - NextStatusMailbox->Fields.CommandIdentifier; - DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1]; - Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus; - Command->V2.RequestSenseLength = - NextStatusMailbox->Fields.RequestSenseLength; - Command->V2.DataTransferResidue = - NextStatusMailbox->Fields.DataTransferResidue; - NextStatusMailbox->Words[0] = 0; - if (++NextStatusMailbox > Controller->V2.LastStatusMailbox) - NextStatusMailbox = Controller->V2.FirstStatusMailbox; - DAC960_V2_ProcessCompletedCommand(Command); - } - Controller->V2.NextStatusMailbox = NextStatusMailbox; - /* - Attempt to remove additional I/O Requests from the Controller's - I/O Request Queue and queue them to the Controller. - */ - DAC960_ProcessRequest(Controller); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - return IRQ_HANDLED; -} - -/* - DAC960_BA_InterruptHandler handles hardware interrupts from DAC960 BA Series - Controllers. -*/ - -static irqreturn_t DAC960_BA_InterruptHandler(int IRQ_Channel, - void *DeviceIdentifier) -{ - DAC960_Controller_T *Controller = DeviceIdentifier; - void __iomem *ControllerBaseAddress = Controller->BaseAddress; - DAC960_V2_StatusMailbox_T *NextStatusMailbox; - unsigned long flags; - - spin_lock_irqsave(&Controller->queue_lock, flags); - DAC960_BA_AcknowledgeInterrupt(ControllerBaseAddress); - NextStatusMailbox = Controller->V2.NextStatusMailbox; - while (NextStatusMailbox->Fields.CommandIdentifier > 0) - { - DAC960_V2_CommandIdentifier_T CommandIdentifier = - NextStatusMailbox->Fields.CommandIdentifier; - DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1]; - Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus; - Command->V2.RequestSenseLength = - NextStatusMailbox->Fields.RequestSenseLength; - Command->V2.DataTransferResidue = - NextStatusMailbox->Fields.DataTransferResidue; - NextStatusMailbox->Words[0] = 0; - if (++NextStatusMailbox > Controller->V2.LastStatusMailbox) - NextStatusMailbox = Controller->V2.FirstStatusMailbox; - DAC960_V2_ProcessCompletedCommand(Command); - } - Controller->V2.NextStatusMailbox = NextStatusMailbox; - /* - Attempt to remove additional I/O Requests from the Controller's - I/O Request Queue and queue them to the Controller. - */ - DAC960_ProcessRequest(Controller); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - return IRQ_HANDLED; -} - - -/* - DAC960_LP_InterruptHandler handles hardware interrupts from DAC960 LP Series - Controllers. -*/ - -static irqreturn_t DAC960_LP_InterruptHandler(int IRQ_Channel, - void *DeviceIdentifier) -{ - DAC960_Controller_T *Controller = DeviceIdentifier; - void __iomem *ControllerBaseAddress = Controller->BaseAddress; - DAC960_V2_StatusMailbox_T *NextStatusMailbox; - unsigned long flags; - - spin_lock_irqsave(&Controller->queue_lock, flags); - DAC960_LP_AcknowledgeInterrupt(ControllerBaseAddress); - NextStatusMailbox = Controller->V2.NextStatusMailbox; - while (NextStatusMailbox->Fields.CommandIdentifier > 0) - { - DAC960_V2_CommandIdentifier_T CommandIdentifier = - NextStatusMailbox->Fields.CommandIdentifier; - DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1]; - Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus; - Command->V2.RequestSenseLength = - NextStatusMailbox->Fields.RequestSenseLength; - Command->V2.DataTransferResidue = - NextStatusMailbox->Fields.DataTransferResidue; - NextStatusMailbox->Words[0] = 0; - if (++NextStatusMailbox > Controller->V2.LastStatusMailbox) - NextStatusMailbox = Controller->V2.FirstStatusMailbox; - DAC960_V2_ProcessCompletedCommand(Command); - } - Controller->V2.NextStatusMailbox = NextStatusMailbox; - /* - Attempt to remove additional I/O Requests from the Controller's - I/O Request Queue and queue them to the Controller. - */ - DAC960_ProcessRequest(Controller); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - return IRQ_HANDLED; -} - - -/* - DAC960_LA_InterruptHandler handles hardware interrupts from DAC960 LA Series - Controllers. -*/ - -static irqreturn_t DAC960_LA_InterruptHandler(int IRQ_Channel, - void *DeviceIdentifier) -{ - DAC960_Controller_T *Controller = DeviceIdentifier; - void __iomem *ControllerBaseAddress = Controller->BaseAddress; - DAC960_V1_StatusMailbox_T *NextStatusMailbox; - unsigned long flags; - - spin_lock_irqsave(&Controller->queue_lock, flags); - DAC960_LA_AcknowledgeInterrupt(ControllerBaseAddress); - NextStatusMailbox = Controller->V1.NextStatusMailbox; - while (NextStatusMailbox->Fields.Valid) - { - DAC960_V1_CommandIdentifier_T CommandIdentifier = - NextStatusMailbox->Fields.CommandIdentifier; - DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1]; - Command->V1.CommandStatus = NextStatusMailbox->Fields.CommandStatus; - NextStatusMailbox->Word = 0; - if (++NextStatusMailbox > Controller->V1.LastStatusMailbox) - NextStatusMailbox = Controller->V1.FirstStatusMailbox; - DAC960_V1_ProcessCompletedCommand(Command); - } - Controller->V1.NextStatusMailbox = NextStatusMailbox; - /* - Attempt to remove additional I/O Requests from the Controller's - I/O Request Queue and queue them to the Controller. - */ - DAC960_ProcessRequest(Controller); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - return IRQ_HANDLED; -} - - -/* - DAC960_PG_InterruptHandler handles hardware interrupts from DAC960 PG Series - Controllers. -*/ - -static irqreturn_t DAC960_PG_InterruptHandler(int IRQ_Channel, - void *DeviceIdentifier) -{ - DAC960_Controller_T *Controller = DeviceIdentifier; - void __iomem *ControllerBaseAddress = Controller->BaseAddress; - DAC960_V1_StatusMailbox_T *NextStatusMailbox; - unsigned long flags; - - spin_lock_irqsave(&Controller->queue_lock, flags); - DAC960_PG_AcknowledgeInterrupt(ControllerBaseAddress); - NextStatusMailbox = Controller->V1.NextStatusMailbox; - while (NextStatusMailbox->Fields.Valid) - { - DAC960_V1_CommandIdentifier_T CommandIdentifier = - NextStatusMailbox->Fields.CommandIdentifier; - DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1]; - Command->V1.CommandStatus = NextStatusMailbox->Fields.CommandStatus; - NextStatusMailbox->Word = 0; - if (++NextStatusMailbox > Controller->V1.LastStatusMailbox) - NextStatusMailbox = Controller->V1.FirstStatusMailbox; - DAC960_V1_ProcessCompletedCommand(Command); - } - Controller->V1.NextStatusMailbox = NextStatusMailbox; - /* - Attempt to remove additional I/O Requests from the Controller's - I/O Request Queue and queue them to the Controller. - */ - DAC960_ProcessRequest(Controller); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - return IRQ_HANDLED; -} - - -/* - DAC960_PD_InterruptHandler handles hardware interrupts from DAC960 PD Series - Controllers. -*/ - -static irqreturn_t DAC960_PD_InterruptHandler(int IRQ_Channel, - void *DeviceIdentifier) -{ - DAC960_Controller_T *Controller = DeviceIdentifier; - void __iomem *ControllerBaseAddress = Controller->BaseAddress; - unsigned long flags; - - spin_lock_irqsave(&Controller->queue_lock, flags); - while (DAC960_PD_StatusAvailableP(ControllerBaseAddress)) - { - DAC960_V1_CommandIdentifier_T CommandIdentifier = - DAC960_PD_ReadStatusCommandIdentifier(ControllerBaseAddress); - DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1]; - Command->V1.CommandStatus = - DAC960_PD_ReadStatusRegister(ControllerBaseAddress); - DAC960_PD_AcknowledgeInterrupt(ControllerBaseAddress); - DAC960_PD_AcknowledgeStatus(ControllerBaseAddress); - DAC960_V1_ProcessCompletedCommand(Command); - } - /* - Attempt to remove additional I/O Requests from the Controller's - I/O Request Queue and queue them to the Controller. - */ - DAC960_ProcessRequest(Controller); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - return IRQ_HANDLED; -} - - -/* - DAC960_P_InterruptHandler handles hardware interrupts from DAC960 P Series - Controllers. - - Translations of DAC960_V1_Enquiry and DAC960_V1_GetDeviceState rely - on the data having been placed into DAC960_Controller_T, rather than - an arbitrary buffer. -*/ - -static irqreturn_t DAC960_P_InterruptHandler(int IRQ_Channel, - void *DeviceIdentifier) -{ - DAC960_Controller_T *Controller = DeviceIdentifier; - void __iomem *ControllerBaseAddress = Controller->BaseAddress; - unsigned long flags; - - spin_lock_irqsave(&Controller->queue_lock, flags); - while (DAC960_PD_StatusAvailableP(ControllerBaseAddress)) - { - DAC960_V1_CommandIdentifier_T CommandIdentifier = - DAC960_PD_ReadStatusCommandIdentifier(ControllerBaseAddress); - DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1]; - DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox; - DAC960_V1_CommandOpcode_T CommandOpcode = - CommandMailbox->Common.CommandOpcode; - Command->V1.CommandStatus = - DAC960_PD_ReadStatusRegister(ControllerBaseAddress); - DAC960_PD_AcknowledgeInterrupt(ControllerBaseAddress); - DAC960_PD_AcknowledgeStatus(ControllerBaseAddress); - switch (CommandOpcode) - { - case DAC960_V1_Enquiry_Old: - Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Enquiry; - DAC960_P_To_PD_TranslateEnquiry(Controller->V1.NewEnquiry); - break; - case DAC960_V1_GetDeviceState_Old: - Command->V1.CommandMailbox.Common.CommandOpcode = - DAC960_V1_GetDeviceState; - DAC960_P_To_PD_TranslateDeviceState(Controller->V1.NewDeviceState); - break; - case DAC960_V1_Read_Old: - Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Read; - DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox); - break; - case DAC960_V1_Write_Old: - Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Write; - DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox); - break; - case DAC960_V1_ReadWithScatterGather_Old: - Command->V1.CommandMailbox.Common.CommandOpcode = - DAC960_V1_ReadWithScatterGather; - DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox); - break; - case DAC960_V1_WriteWithScatterGather_Old: - Command->V1.CommandMailbox.Common.CommandOpcode = - DAC960_V1_WriteWithScatterGather; - DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox); - break; - default: - break; - } - DAC960_V1_ProcessCompletedCommand(Command); - } - /* - Attempt to remove additional I/O Requests from the Controller's - I/O Request Queue and queue them to the Controller. - */ - DAC960_ProcessRequest(Controller); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - return IRQ_HANDLED; -} - - -/* - DAC960_V1_QueueMonitoringCommand queues a Monitoring Command to DAC960 V1 - Firmware Controllers. -*/ - -static void DAC960_V1_QueueMonitoringCommand(DAC960_Command_T *Command) -{ - DAC960_Controller_T *Controller = Command->Controller; - DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox; - DAC960_V1_ClearCommand(Command); - Command->CommandType = DAC960_MonitoringCommand; - CommandMailbox->Type3.CommandOpcode = DAC960_V1_Enquiry; - CommandMailbox->Type3.BusAddress = Controller->V1.NewEnquiryDMA; - DAC960_QueueCommand(Command); -} - - -/* - DAC960_V2_QueueMonitoringCommand queues a Monitoring Command to DAC960 V2 - Firmware Controllers. -*/ - -static void DAC960_V2_QueueMonitoringCommand(DAC960_Command_T *Command) -{ - DAC960_Controller_T *Controller = Command->Controller; - DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; - DAC960_V2_ClearCommand(Command); - Command->CommandType = DAC960_MonitoringCommand; - CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL; - CommandMailbox->ControllerInfo.CommandControlBits - .DataTransferControllerToHost = true; - CommandMailbox->ControllerInfo.CommandControlBits - .NoAutoRequestSense = true; - CommandMailbox->ControllerInfo.DataTransferSize = - sizeof(DAC960_V2_ControllerInfo_T); - CommandMailbox->ControllerInfo.ControllerNumber = 0; - CommandMailbox->ControllerInfo.IOCTL_Opcode = DAC960_V2_GetControllerInfo; - CommandMailbox->ControllerInfo.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentDataPointer = - Controller->V2.NewControllerInformationDMA; - CommandMailbox->ControllerInfo.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentByteCount = - CommandMailbox->ControllerInfo.DataTransferSize; - DAC960_QueueCommand(Command); -} - - -/* - DAC960_MonitoringTimerFunction is the timer function for monitoring - the status of DAC960 Controllers. -*/ - -static void DAC960_MonitoringTimerFunction(struct timer_list *t) -{ - DAC960_Controller_T *Controller = from_timer(Controller, t, MonitoringTimer); - DAC960_Command_T *Command; - unsigned long flags; - - if (Controller->FirmwareType == DAC960_V1_Controller) - { - spin_lock_irqsave(&Controller->queue_lock, flags); - /* - Queue a Status Monitoring Command to Controller. - */ - Command = DAC960_AllocateCommand(Controller); - if (Command != NULL) - DAC960_V1_QueueMonitoringCommand(Command); - else Controller->MonitoringCommandDeferred = true; - spin_unlock_irqrestore(&Controller->queue_lock, flags); - } - else - { - DAC960_V2_ControllerInfo_T *ControllerInfo = - &Controller->V2.ControllerInformation; - unsigned int StatusChangeCounter = - Controller->V2.HealthStatusBuffer->StatusChangeCounter; - bool ForceMonitoringCommand = false; - if (time_after(jiffies, Controller->SecondaryMonitoringTime - + DAC960_SecondaryMonitoringInterval)) - { - int LogicalDriveNumber; - for (LogicalDriveNumber = 0; - LogicalDriveNumber < DAC960_MaxLogicalDrives; - LogicalDriveNumber++) - { - DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo = - Controller->V2.LogicalDeviceInformation[LogicalDriveNumber]; - if (LogicalDeviceInfo == NULL) continue; - if (!LogicalDeviceInfo->LogicalDeviceControl - .LogicalDeviceInitialized) - { - ForceMonitoringCommand = true; - break; - } - } - Controller->SecondaryMonitoringTime = jiffies; - } - if (StatusChangeCounter == Controller->V2.StatusChangeCounter && - Controller->V2.HealthStatusBuffer->NextEventSequenceNumber - == Controller->V2.NextEventSequenceNumber && - (ControllerInfo->BackgroundInitializationsActive + - ControllerInfo->LogicalDeviceInitializationsActive + - ControllerInfo->PhysicalDeviceInitializationsActive + - ControllerInfo->ConsistencyChecksActive + - ControllerInfo->RebuildsActive + - ControllerInfo->OnlineExpansionsActive == 0 || - time_before(jiffies, Controller->PrimaryMonitoringTime - + DAC960_MonitoringTimerInterval)) && - !ForceMonitoringCommand) - { - Controller->MonitoringTimer.expires = - jiffies + DAC960_HealthStatusMonitoringInterval; - add_timer(&Controller->MonitoringTimer); - return; - } - Controller->V2.StatusChangeCounter = StatusChangeCounter; - Controller->PrimaryMonitoringTime = jiffies; - - spin_lock_irqsave(&Controller->queue_lock, flags); - /* - Queue a Status Monitoring Command to Controller. - */ - Command = DAC960_AllocateCommand(Controller); - if (Command != NULL) - DAC960_V2_QueueMonitoringCommand(Command); - else Controller->MonitoringCommandDeferred = true; - spin_unlock_irqrestore(&Controller->queue_lock, flags); - /* - Wake up any processes waiting on a Health Status Buffer change. - */ - wake_up(&Controller->HealthStatusWaitQueue); - } -} - -/* - DAC960_CheckStatusBuffer verifies that there is room to hold ByteCount - additional bytes in the Combined Status Buffer and grows the buffer if - necessary. It returns true if there is enough room and false otherwise. -*/ - -static bool DAC960_CheckStatusBuffer(DAC960_Controller_T *Controller, - unsigned int ByteCount) -{ - unsigned char *NewStatusBuffer; - if (Controller->InitialStatusLength + 1 + - Controller->CurrentStatusLength + ByteCount + 1 <= - Controller->CombinedStatusBufferLength) - return true; - if (Controller->CombinedStatusBufferLength == 0) - { - unsigned int NewStatusBufferLength = DAC960_InitialStatusBufferSize; - while (NewStatusBufferLength < ByteCount) - NewStatusBufferLength *= 2; - Controller->CombinedStatusBuffer = kmalloc(NewStatusBufferLength, - GFP_ATOMIC); - if (Controller->CombinedStatusBuffer == NULL) return false; - Controller->CombinedStatusBufferLength = NewStatusBufferLength; - return true; - } - NewStatusBuffer = kmalloc_array(2, Controller->CombinedStatusBufferLength, - GFP_ATOMIC); - if (NewStatusBuffer == NULL) - { - DAC960_Warning("Unable to expand Combined Status Buffer - Truncating\n", - Controller); - return false; - } - memcpy(NewStatusBuffer, Controller->CombinedStatusBuffer, - Controller->CombinedStatusBufferLength); - kfree(Controller->CombinedStatusBuffer); - Controller->CombinedStatusBuffer = NewStatusBuffer; - Controller->CombinedStatusBufferLength *= 2; - Controller->CurrentStatusBuffer = - &NewStatusBuffer[Controller->InitialStatusLength + 1]; - return true; -} - - -/* - DAC960_Message prints Driver Messages. -*/ - -static void DAC960_Message(DAC960_MessageLevel_T MessageLevel, - unsigned char *Format, - DAC960_Controller_T *Controller, - ...) -{ - static unsigned char Buffer[DAC960_LineBufferSize]; - static bool BeginningOfLine = true; - va_list Arguments; - int Length = 0; - va_start(Arguments, Controller); - Length = vsprintf(Buffer, Format, Arguments); - va_end(Arguments); - if (Controller == NULL) - printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel], - DAC960_ControllerCount, Buffer); - else if (MessageLevel == DAC960_AnnounceLevel || - MessageLevel == DAC960_InfoLevel) - { - if (!Controller->ControllerInitialized) - { - if (DAC960_CheckStatusBuffer(Controller, Length)) - { - strcpy(&Controller->CombinedStatusBuffer - [Controller->InitialStatusLength], - Buffer); - Controller->InitialStatusLength += Length; - Controller->CurrentStatusBuffer = - &Controller->CombinedStatusBuffer - [Controller->InitialStatusLength + 1]; - } - if (MessageLevel == DAC960_AnnounceLevel) - { - static int AnnouncementLines = 0; - if (++AnnouncementLines <= 2) - printk("%sDAC960: %s", DAC960_MessageLevelMap[MessageLevel], - Buffer); - } - else - { - if (BeginningOfLine) - { - if (Buffer[0] != '\n' || Length > 1) - printk("%sDAC960#%d: %s", - DAC960_MessageLevelMap[MessageLevel], - Controller->ControllerNumber, Buffer); - } - else printk("%s", Buffer); - } - } - else if (DAC960_CheckStatusBuffer(Controller, Length)) - { - strcpy(&Controller->CurrentStatusBuffer[ - Controller->CurrentStatusLength], Buffer); - Controller->CurrentStatusLength += Length; - } - } - else if (MessageLevel == DAC960_ProgressLevel) - { - strcpy(Controller->ProgressBuffer, Buffer); - Controller->ProgressBufferLength = Length; - if (Controller->EphemeralProgressMessage) - { - if (time_after_eq(jiffies, Controller->LastProgressReportTime - + DAC960_ProgressReportingInterval)) - { - printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel], - Controller->ControllerNumber, Buffer); - Controller->LastProgressReportTime = jiffies; - } - } - else printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel], - Controller->ControllerNumber, Buffer); - } - else if (MessageLevel == DAC960_UserCriticalLevel) - { - strcpy(&Controller->UserStatusBuffer[Controller->UserStatusLength], - Buffer); - Controller->UserStatusLength += Length; - if (Buffer[0] != '\n' || Length > 1) - printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel], - Controller->ControllerNumber, Buffer); - } - else - { - if (BeginningOfLine) - printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel], - Controller->ControllerNumber, Buffer); - else printk("%s", Buffer); - } - BeginningOfLine = (Buffer[Length-1] == '\n'); -} - - -/* - DAC960_ParsePhysicalDevice parses spaces followed by a Physical Device - Channel:TargetID specification from a User Command string. It updates - Channel and TargetID and returns true on success and false on failure. -*/ - -static bool DAC960_ParsePhysicalDevice(DAC960_Controller_T *Controller, - char *UserCommandString, - unsigned char *Channel, - unsigned char *TargetID) -{ - char *NewUserCommandString = UserCommandString; - unsigned long XChannel, XTargetID; - while (*UserCommandString == ' ') UserCommandString++; - if (UserCommandString == NewUserCommandString) - return false; - XChannel = simple_strtoul(UserCommandString, &NewUserCommandString, 10); - if (NewUserCommandString == UserCommandString || - *NewUserCommandString != ':' || - XChannel >= Controller->Channels) - return false; - UserCommandString = ++NewUserCommandString; - XTargetID = simple_strtoul(UserCommandString, &NewUserCommandString, 10); - if (NewUserCommandString == UserCommandString || - *NewUserCommandString != '\0' || - XTargetID >= Controller->Targets) - return false; - *Channel = XChannel; - *TargetID = XTargetID; - return true; -} - - -/* - DAC960_ParseLogicalDrive parses spaces followed by a Logical Drive Number - specification from a User Command string. It updates LogicalDriveNumber and - returns true on success and false on failure. -*/ - -static bool DAC960_ParseLogicalDrive(DAC960_Controller_T *Controller, - char *UserCommandString, - unsigned char *LogicalDriveNumber) -{ - char *NewUserCommandString = UserCommandString; - unsigned long XLogicalDriveNumber; - while (*UserCommandString == ' ') UserCommandString++; - if (UserCommandString == NewUserCommandString) - return false; - XLogicalDriveNumber = - simple_strtoul(UserCommandString, &NewUserCommandString, 10); - if (NewUserCommandString == UserCommandString || - *NewUserCommandString != '\0' || - XLogicalDriveNumber > DAC960_MaxLogicalDrives - 1) - return false; - *LogicalDriveNumber = XLogicalDriveNumber; - return true; -} - - -/* - DAC960_V1_SetDeviceState sets the Device State for a Physical Device for - DAC960 V1 Firmware Controllers. -*/ - -static void DAC960_V1_SetDeviceState(DAC960_Controller_T *Controller, - DAC960_Command_T *Command, - unsigned char Channel, - unsigned char TargetID, - DAC960_V1_PhysicalDeviceState_T - DeviceState, - const unsigned char *DeviceStateString) -{ - DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox; - CommandMailbox->Type3D.CommandOpcode = DAC960_V1_StartDevice; - CommandMailbox->Type3D.Channel = Channel; - CommandMailbox->Type3D.TargetID = TargetID; - CommandMailbox->Type3D.DeviceState = DeviceState; - CommandMailbox->Type3D.Modifier = 0; - DAC960_ExecuteCommand(Command); - switch (Command->V1.CommandStatus) - { - case DAC960_V1_NormalCompletion: - DAC960_UserCritical("%s of Physical Device %d:%d Succeeded\n", Controller, - DeviceStateString, Channel, TargetID); - break; - case DAC960_V1_UnableToStartDevice: - DAC960_UserCritical("%s of Physical Device %d:%d Failed - " - "Unable to Start Device\n", Controller, - DeviceStateString, Channel, TargetID); - break; - case DAC960_V1_NoDeviceAtAddress: - DAC960_UserCritical("%s of Physical Device %d:%d Failed - " - "No Device at Address\n", Controller, - DeviceStateString, Channel, TargetID); - break; - case DAC960_V1_InvalidChannelOrTargetOrModifier: - DAC960_UserCritical("%s of Physical Device %d:%d Failed - " - "Invalid Channel or Target or Modifier\n", - Controller, DeviceStateString, Channel, TargetID); - break; - case DAC960_V1_ChannelBusy: - DAC960_UserCritical("%s of Physical Device %d:%d Failed - " - "Channel Busy\n", Controller, - DeviceStateString, Channel, TargetID); - break; - default: - DAC960_UserCritical("%s of Physical Device %d:%d Failed - " - "Unexpected Status %04X\n", Controller, - DeviceStateString, Channel, TargetID, - Command->V1.CommandStatus); - break; - } -} - - -/* - DAC960_V1_ExecuteUserCommand executes a User Command for DAC960 V1 Firmware - Controllers. -*/ - -static bool DAC960_V1_ExecuteUserCommand(DAC960_Controller_T *Controller, - unsigned char *UserCommand) -{ - DAC960_Command_T *Command; - DAC960_V1_CommandMailbox_T *CommandMailbox; - unsigned long flags; - unsigned char Channel, TargetID, LogicalDriveNumber; - - spin_lock_irqsave(&Controller->queue_lock, flags); - while ((Command = DAC960_AllocateCommand(Controller)) == NULL) - DAC960_WaitForCommand(Controller); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - Controller->UserStatusLength = 0; - DAC960_V1_ClearCommand(Command); - Command->CommandType = DAC960_ImmediateCommand; - CommandMailbox = &Command->V1.CommandMailbox; - if (strcmp(UserCommand, "flush-cache") == 0) - { - CommandMailbox->Type3.CommandOpcode = DAC960_V1_Flush; - DAC960_ExecuteCommand(Command); - DAC960_UserCritical("Cache Flush Completed\n", Controller); - } - else if (strncmp(UserCommand, "kill", 4) == 0 && - DAC960_ParsePhysicalDevice(Controller, &UserCommand[4], - &Channel, &TargetID)) - { - DAC960_V1_DeviceState_T *DeviceState = - &Controller->V1.DeviceState[Channel][TargetID]; - if (DeviceState->Present && - DeviceState->DeviceType == DAC960_V1_DiskType && - DeviceState->DeviceState != DAC960_V1_Device_Dead) - DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID, - DAC960_V1_Device_Dead, "Kill"); - else DAC960_UserCritical("Kill of Physical Device %d:%d Illegal\n", - Controller, Channel, TargetID); - } - else if (strncmp(UserCommand, "make-online", 11) == 0 && - DAC960_ParsePhysicalDevice(Controller, &UserCommand[11], - &Channel, &TargetID)) - { - DAC960_V1_DeviceState_T *DeviceState = - &Controller->V1.DeviceState[Channel][TargetID]; - if (DeviceState->Present && - DeviceState->DeviceType == DAC960_V1_DiskType && - DeviceState->DeviceState == DAC960_V1_Device_Dead) - DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID, - DAC960_V1_Device_Online, "Make Online"); - else DAC960_UserCritical("Make Online of Physical Device %d:%d Illegal\n", - Controller, Channel, TargetID); - - } - else if (strncmp(UserCommand, "make-standby", 12) == 0 && - DAC960_ParsePhysicalDevice(Controller, &UserCommand[12], - &Channel, &TargetID)) - { - DAC960_V1_DeviceState_T *DeviceState = - &Controller->V1.DeviceState[Channel][TargetID]; - if (DeviceState->Present && - DeviceState->DeviceType == DAC960_V1_DiskType && - DeviceState->DeviceState == DAC960_V1_Device_Dead) - DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID, - DAC960_V1_Device_Standby, "Make Standby"); - else DAC960_UserCritical("Make Standby of Physical " - "Device %d:%d Illegal\n", - Controller, Channel, TargetID); - } - else if (strncmp(UserCommand, "rebuild", 7) == 0 && - DAC960_ParsePhysicalDevice(Controller, &UserCommand[7], - &Channel, &TargetID)) - { - CommandMailbox->Type3D.CommandOpcode = DAC960_V1_RebuildAsync; - CommandMailbox->Type3D.Channel = Channel; - CommandMailbox->Type3D.TargetID = TargetID; - DAC960_ExecuteCommand(Command); - switch (Command->V1.CommandStatus) - { - case DAC960_V1_NormalCompletion: - DAC960_UserCritical("Rebuild of Physical Device %d:%d Initiated\n", - Controller, Channel, TargetID); - break; - case DAC960_V1_AttemptToRebuildOnlineDrive: - DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - " - "Attempt to Rebuild Online or " - "Unresponsive Drive\n", - Controller, Channel, TargetID); - break; - case DAC960_V1_NewDiskFailedDuringRebuild: - DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - " - "New Disk Failed During Rebuild\n", - Controller, Channel, TargetID); - break; - case DAC960_V1_InvalidDeviceAddress: - DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - " - "Invalid Device Address\n", - Controller, Channel, TargetID); - break; - case DAC960_V1_RebuildOrCheckAlreadyInProgress: - DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - " - "Rebuild or Consistency Check Already " - "in Progress\n", Controller, Channel, TargetID); - break; - default: - DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - " - "Unexpected Status %04X\n", Controller, - Channel, TargetID, Command->V1.CommandStatus); - break; - } - } - else if (strncmp(UserCommand, "check-consistency", 17) == 0 && - DAC960_ParseLogicalDrive(Controller, &UserCommand[17], - &LogicalDriveNumber)) - { - CommandMailbox->Type3C.CommandOpcode = DAC960_V1_CheckConsistencyAsync; - CommandMailbox->Type3C.LogicalDriveNumber = LogicalDriveNumber; - CommandMailbox->Type3C.AutoRestore = true; - DAC960_ExecuteCommand(Command); - switch (Command->V1.CommandStatus) - { - case DAC960_V1_NormalCompletion: - DAC960_UserCritical("Consistency Check of Logical Drive %d " - "(/dev/rd/c%dd%d) Initiated\n", - Controller, LogicalDriveNumber, - Controller->ControllerNumber, - LogicalDriveNumber); - break; - case DAC960_V1_DependentDiskIsDead: - DAC960_UserCritical("Consistency Check of Logical Drive %d " - "(/dev/rd/c%dd%d) Failed - " - "Dependent Physical Device is DEAD\n", - Controller, LogicalDriveNumber, - Controller->ControllerNumber, - LogicalDriveNumber); - break; - case DAC960_V1_InvalidOrNonredundantLogicalDrive: - DAC960_UserCritical("Consistency Check of Logical Drive %d " - "(/dev/rd/c%dd%d) Failed - " - "Invalid or Nonredundant Logical Drive\n", - Controller, LogicalDriveNumber, - Controller->ControllerNumber, - LogicalDriveNumber); - break; - case DAC960_V1_RebuildOrCheckAlreadyInProgress: - DAC960_UserCritical("Consistency Check of Logical Drive %d " - "(/dev/rd/c%dd%d) Failed - Rebuild or " - "Consistency Check Already in Progress\n", - Controller, LogicalDriveNumber, - Controller->ControllerNumber, - LogicalDriveNumber); - break; - default: - DAC960_UserCritical("Consistency Check of Logical Drive %d " - "(/dev/rd/c%dd%d) Failed - " - "Unexpected Status %04X\n", - Controller, LogicalDriveNumber, - Controller->ControllerNumber, - LogicalDriveNumber, Command->V1.CommandStatus); - break; - } - } - else if (strcmp(UserCommand, "cancel-rebuild") == 0 || - strcmp(UserCommand, "cancel-consistency-check") == 0) - { - /* - the OldRebuildRateConstant is never actually used - once its value is retrieved from the controller. - */ - unsigned char *OldRebuildRateConstant; - dma_addr_t OldRebuildRateConstantDMA; - - OldRebuildRateConstant = pci_alloc_consistent( Controller->PCIDevice, - sizeof(char), &OldRebuildRateConstantDMA); - if (OldRebuildRateConstant == NULL) { - DAC960_UserCritical("Cancellation of Rebuild or " - "Consistency Check Failed - " - "Out of Memory", - Controller); - goto failure; - } - CommandMailbox->Type3R.CommandOpcode = DAC960_V1_RebuildControl; - CommandMailbox->Type3R.RebuildRateConstant = 0xFF; - CommandMailbox->Type3R.BusAddress = OldRebuildRateConstantDMA; - DAC960_ExecuteCommand(Command); - switch (Command->V1.CommandStatus) - { - case DAC960_V1_NormalCompletion: - DAC960_UserCritical("Rebuild or Consistency Check Cancelled\n", - Controller); - break; - default: - DAC960_UserCritical("Cancellation of Rebuild or " - "Consistency Check Failed - " - "Unexpected Status %04X\n", - Controller, Command->V1.CommandStatus); - break; - } -failure: - pci_free_consistent(Controller->PCIDevice, sizeof(char), - OldRebuildRateConstant, OldRebuildRateConstantDMA); - } - else DAC960_UserCritical("Illegal User Command: '%s'\n", - Controller, UserCommand); - - spin_lock_irqsave(&Controller->queue_lock, flags); - DAC960_DeallocateCommand(Command); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - return true; -} - - -/* - DAC960_V2_TranslatePhysicalDevice translates a Physical Device Channel and - TargetID into a Logical Device. It returns true on success and false - on failure. -*/ - -static bool DAC960_V2_TranslatePhysicalDevice(DAC960_Command_T *Command, - unsigned char Channel, - unsigned char TargetID, - unsigned short - *LogicalDeviceNumber) -{ - DAC960_V2_CommandMailbox_T SavedCommandMailbox, *CommandMailbox; - DAC960_Controller_T *Controller = Command->Controller; - - CommandMailbox = &Command->V2.CommandMailbox; - memcpy(&SavedCommandMailbox, CommandMailbox, - sizeof(DAC960_V2_CommandMailbox_T)); - - CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL; - CommandMailbox->PhysicalDeviceInfo.CommandControlBits - .DataTransferControllerToHost = true; - CommandMailbox->PhysicalDeviceInfo.CommandControlBits - .NoAutoRequestSense = true; - CommandMailbox->PhysicalDeviceInfo.DataTransferSize = - sizeof(DAC960_V2_PhysicalToLogicalDevice_T); - CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID = TargetID; - CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel = Channel; - CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode = - DAC960_V2_TranslatePhysicalToLogicalDevice; - CommandMailbox->Common.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentDataPointer = - Controller->V2.PhysicalToLogicalDeviceDMA; - CommandMailbox->Common.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentByteCount = - CommandMailbox->Common.DataTransferSize; - - DAC960_ExecuteCommand(Command); - *LogicalDeviceNumber = Controller->V2.PhysicalToLogicalDevice->LogicalDeviceNumber; - - memcpy(CommandMailbox, &SavedCommandMailbox, - sizeof(DAC960_V2_CommandMailbox_T)); - return (Command->V2.CommandStatus == DAC960_V2_NormalCompletion); -} - - -/* - DAC960_V2_ExecuteUserCommand executes a User Command for DAC960 V2 Firmware - Controllers. -*/ - -static bool DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller, - unsigned char *UserCommand) -{ - DAC960_Command_T *Command; - DAC960_V2_CommandMailbox_T *CommandMailbox; - unsigned long flags; - unsigned char Channel, TargetID, LogicalDriveNumber; - unsigned short LogicalDeviceNumber; - - spin_lock_irqsave(&Controller->queue_lock, flags); - while ((Command = DAC960_AllocateCommand(Controller)) == NULL) - DAC960_WaitForCommand(Controller); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - Controller->UserStatusLength = 0; - DAC960_V2_ClearCommand(Command); - Command->CommandType = DAC960_ImmediateCommand; - CommandMailbox = &Command->V2.CommandMailbox; - CommandMailbox->Common.CommandOpcode = DAC960_V2_IOCTL; - CommandMailbox->Common.CommandControlBits.DataTransferControllerToHost = true; - CommandMailbox->Common.CommandControlBits.NoAutoRequestSense = true; - if (strcmp(UserCommand, "flush-cache") == 0) - { - CommandMailbox->DeviceOperation.IOCTL_Opcode = DAC960_V2_PauseDevice; - CommandMailbox->DeviceOperation.OperationDevice = - DAC960_V2_RAID_Controller; - DAC960_ExecuteCommand(Command); - DAC960_UserCritical("Cache Flush Completed\n", Controller); - } - else if (strncmp(UserCommand, "kill", 4) == 0 && - DAC960_ParsePhysicalDevice(Controller, &UserCommand[4], - &Channel, &TargetID) && - DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID, - &LogicalDeviceNumber)) - { - CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber = - LogicalDeviceNumber; - CommandMailbox->SetDeviceState.IOCTL_Opcode = - DAC960_V2_SetDeviceState; - CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState = - DAC960_V2_Device_Dead; - DAC960_ExecuteCommand(Command); - DAC960_UserCritical("Kill of Physical Device %d:%d %s\n", - Controller, Channel, TargetID, - (Command->V2.CommandStatus - == DAC960_V2_NormalCompletion - ? "Succeeded" : "Failed")); - } - else if (strncmp(UserCommand, "make-online", 11) == 0 && - DAC960_ParsePhysicalDevice(Controller, &UserCommand[11], - &Channel, &TargetID) && - DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID, - &LogicalDeviceNumber)) - { - CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber = - LogicalDeviceNumber; - CommandMailbox->SetDeviceState.IOCTL_Opcode = - DAC960_V2_SetDeviceState; - CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState = - DAC960_V2_Device_Online; - DAC960_ExecuteCommand(Command); - DAC960_UserCritical("Make Online of Physical Device %d:%d %s\n", - Controller, Channel, TargetID, - (Command->V2.CommandStatus - == DAC960_V2_NormalCompletion - ? "Succeeded" : "Failed")); - } - else if (strncmp(UserCommand, "make-standby", 12) == 0 && - DAC960_ParsePhysicalDevice(Controller, &UserCommand[12], - &Channel, &TargetID) && - DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID, - &LogicalDeviceNumber)) - { - CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber = - LogicalDeviceNumber; - CommandMailbox->SetDeviceState.IOCTL_Opcode = - DAC960_V2_SetDeviceState; - CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState = - DAC960_V2_Device_Standby; - DAC960_ExecuteCommand(Command); - DAC960_UserCritical("Make Standby of Physical Device %d:%d %s\n", - Controller, Channel, TargetID, - (Command->V2.CommandStatus - == DAC960_V2_NormalCompletion - ? "Succeeded" : "Failed")); - } - else if (strncmp(UserCommand, "rebuild", 7) == 0 && - DAC960_ParsePhysicalDevice(Controller, &UserCommand[7], - &Channel, &TargetID) && - DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID, - &LogicalDeviceNumber)) - { - CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber = - LogicalDeviceNumber; - CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode = - DAC960_V2_RebuildDeviceStart; - DAC960_ExecuteCommand(Command); - DAC960_UserCritical("Rebuild of Physical Device %d:%d %s\n", - Controller, Channel, TargetID, - (Command->V2.CommandStatus - == DAC960_V2_NormalCompletion - ? "Initiated" : "Not Initiated")); - } - else if (strncmp(UserCommand, "cancel-rebuild", 14) == 0 && - DAC960_ParsePhysicalDevice(Controller, &UserCommand[14], - &Channel, &TargetID) && - DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID, - &LogicalDeviceNumber)) - { - CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber = - LogicalDeviceNumber; - CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode = - DAC960_V2_RebuildDeviceStop; - DAC960_ExecuteCommand(Command); - DAC960_UserCritical("Rebuild of Physical Device %d:%d %s\n", - Controller, Channel, TargetID, - (Command->V2.CommandStatus - == DAC960_V2_NormalCompletion - ? "Cancelled" : "Not Cancelled")); - } - else if (strncmp(UserCommand, "check-consistency", 17) == 0 && - DAC960_ParseLogicalDrive(Controller, &UserCommand[17], - &LogicalDriveNumber)) - { - CommandMailbox->ConsistencyCheck.LogicalDevice.LogicalDeviceNumber = - LogicalDriveNumber; - CommandMailbox->ConsistencyCheck.IOCTL_Opcode = - DAC960_V2_ConsistencyCheckStart; - CommandMailbox->ConsistencyCheck.RestoreConsistency = true; - CommandMailbox->ConsistencyCheck.InitializedAreaOnly = false; - DAC960_ExecuteCommand(Command); - DAC960_UserCritical("Consistency Check of Logical Drive %d " - "(/dev/rd/c%dd%d) %s\n", - Controller, LogicalDriveNumber, - Controller->ControllerNumber, - LogicalDriveNumber, - (Command->V2.CommandStatus - == DAC960_V2_NormalCompletion - ? "Initiated" : "Not Initiated")); - } - else if (strncmp(UserCommand, "cancel-consistency-check", 24) == 0 && - DAC960_ParseLogicalDrive(Controller, &UserCommand[24], - &LogicalDriveNumber)) - { - CommandMailbox->ConsistencyCheck.LogicalDevice.LogicalDeviceNumber = - LogicalDriveNumber; - CommandMailbox->ConsistencyCheck.IOCTL_Opcode = - DAC960_V2_ConsistencyCheckStop; - DAC960_ExecuteCommand(Command); - DAC960_UserCritical("Consistency Check of Logical Drive %d " - "(/dev/rd/c%dd%d) %s\n", - Controller, LogicalDriveNumber, - Controller->ControllerNumber, - LogicalDriveNumber, - (Command->V2.CommandStatus - == DAC960_V2_NormalCompletion - ? "Cancelled" : "Not Cancelled")); - } - else if (strcmp(UserCommand, "perform-discovery") == 0) - { - CommandMailbox->Common.IOCTL_Opcode = DAC960_V2_StartDiscovery; - DAC960_ExecuteCommand(Command); - DAC960_UserCritical("Discovery %s\n", Controller, - (Command->V2.CommandStatus - == DAC960_V2_NormalCompletion - ? "Initiated" : "Not Initiated")); - if (Command->V2.CommandStatus == DAC960_V2_NormalCompletion) - { - CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL; - CommandMailbox->ControllerInfo.CommandControlBits - .DataTransferControllerToHost = true; - CommandMailbox->ControllerInfo.CommandControlBits - .NoAutoRequestSense = true; - CommandMailbox->ControllerInfo.DataTransferSize = - sizeof(DAC960_V2_ControllerInfo_T); - CommandMailbox->ControllerInfo.ControllerNumber = 0; - CommandMailbox->ControllerInfo.IOCTL_Opcode = - DAC960_V2_GetControllerInfo; - /* - * How does this NOT race with the queued Monitoring - * usage of this structure? - */ - CommandMailbox->ControllerInfo.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentDataPointer = - Controller->V2.NewControllerInformationDMA; - CommandMailbox->ControllerInfo.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentByteCount = - CommandMailbox->ControllerInfo.DataTransferSize; - while (1) { - DAC960_ExecuteCommand(Command); - if (!Controller->V2.NewControllerInformation->PhysicalScanActive) - break; - msleep(1000); - } - DAC960_UserCritical("Discovery Completed\n", Controller); - } - } - else if (strcmp(UserCommand, "suppress-enclosure-messages") == 0) - Controller->SuppressEnclosureMessages = true; - else DAC960_UserCritical("Illegal User Command: '%s'\n", - Controller, UserCommand); - - spin_lock_irqsave(&Controller->queue_lock, flags); - DAC960_DeallocateCommand(Command); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - return true; -} - -static int __maybe_unused dac960_proc_show(struct seq_file *m, void *v) -{ - unsigned char *StatusMessage = "OK\n"; - int ControllerNumber; - for (ControllerNumber = 0; - ControllerNumber < DAC960_ControllerCount; - ControllerNumber++) - { - DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber]; - if (Controller == NULL) continue; - if (Controller->MonitoringAlertMode) - { - StatusMessage = "ALERT\n"; - break; - } - } - seq_puts(m, StatusMessage); - return 0; -} - -static int __maybe_unused dac960_initial_status_proc_show(struct seq_file *m, - void *v) -{ - DAC960_Controller_T *Controller = (DAC960_Controller_T *)m->private; - seq_printf(m, "%.*s", Controller->InitialStatusLength, Controller->CombinedStatusBuffer); - return 0; -} - -static int __maybe_unused dac960_current_status_proc_show(struct seq_file *m, - void *v) -{ - DAC960_Controller_T *Controller = (DAC960_Controller_T *) m->private; - unsigned char *StatusMessage = - "No Rebuild or Consistency Check in Progress\n"; - int ProgressMessageLength = strlen(StatusMessage); - if (jiffies != Controller->LastCurrentStatusTime) - { - Controller->CurrentStatusLength = 0; - DAC960_AnnounceDriver(Controller); - DAC960_ReportControllerConfiguration(Controller); - DAC960_ReportDeviceConfiguration(Controller); - if (Controller->ProgressBufferLength > 0) - ProgressMessageLength = Controller->ProgressBufferLength; - if (DAC960_CheckStatusBuffer(Controller, 2 + ProgressMessageLength)) - { - unsigned char *CurrentStatusBuffer = Controller->CurrentStatusBuffer; - CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' '; - CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' '; - if (Controller->ProgressBufferLength > 0) - strcpy(&CurrentStatusBuffer[Controller->CurrentStatusLength], - Controller->ProgressBuffer); - else - strcpy(&CurrentStatusBuffer[Controller->CurrentStatusLength], - StatusMessage); - Controller->CurrentStatusLength += ProgressMessageLength; - } - Controller->LastCurrentStatusTime = jiffies; - } - seq_printf(m, "%.*s", Controller->CurrentStatusLength, Controller->CurrentStatusBuffer); - return 0; -} - -static int dac960_user_command_proc_show(struct seq_file *m, void *v) -{ - DAC960_Controller_T *Controller = (DAC960_Controller_T *)m->private; - - seq_printf(m, "%.*s", Controller->UserStatusLength, Controller->UserStatusBuffer); - return 0; -} - -static int dac960_user_command_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, dac960_user_command_proc_show, PDE_DATA(inode)); -} - -static ssize_t dac960_user_command_proc_write(struct file *file, - const char __user *Buffer, - size_t Count, loff_t *pos) -{ - DAC960_Controller_T *Controller = PDE_DATA(file_inode(file)); - unsigned char CommandBuffer[80]; - int Length; - if (Count > sizeof(CommandBuffer)-1) return -EINVAL; - if (copy_from_user(CommandBuffer, Buffer, Count)) return -EFAULT; - CommandBuffer[Count] = '\0'; - Length = strlen(CommandBuffer); - if (Length > 0 && CommandBuffer[Length-1] == '\n') - CommandBuffer[--Length] = '\0'; - if (Controller->FirmwareType == DAC960_V1_Controller) - return (DAC960_V1_ExecuteUserCommand(Controller, CommandBuffer) - ? Count : -EBUSY); - else - return (DAC960_V2_ExecuteUserCommand(Controller, CommandBuffer) - ? Count : -EBUSY); -} - -static const struct file_operations dac960_user_command_proc_fops = { - .owner = THIS_MODULE, - .open = dac960_user_command_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .write = dac960_user_command_proc_write, -}; - -/* - DAC960_CreateProcEntries creates the /proc/rd/... entries for the - DAC960 Driver. -*/ - -static void DAC960_CreateProcEntries(DAC960_Controller_T *Controller) -{ - struct proc_dir_entry *ControllerProcEntry; - - if (DAC960_ProcDirectoryEntry == NULL) { - DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL); - proc_create_single("status", 0, DAC960_ProcDirectoryEntry, - dac960_proc_show); - } - - snprintf(Controller->ControllerName, sizeof(Controller->ControllerName), - "c%d", Controller->ControllerNumber); - ControllerProcEntry = proc_mkdir(Controller->ControllerName, - DAC960_ProcDirectoryEntry); - proc_create_single_data("initial_status", 0, ControllerProcEntry, - dac960_initial_status_proc_show, Controller); - proc_create_single_data("current_status", 0, ControllerProcEntry, - dac960_current_status_proc_show, Controller); - proc_create_data("user_command", 0600, ControllerProcEntry, &dac960_user_command_proc_fops, Controller); - Controller->ControllerProcEntry = ControllerProcEntry; -} - - -/* - DAC960_DestroyProcEntries destroys the /proc/rd/... entries for the - DAC960 Driver. -*/ - -static void DAC960_DestroyProcEntries(DAC960_Controller_T *Controller) -{ - if (Controller->ControllerProcEntry == NULL) - return; - remove_proc_entry("initial_status", Controller->ControllerProcEntry); - remove_proc_entry("current_status", Controller->ControllerProcEntry); - remove_proc_entry("user_command", Controller->ControllerProcEntry); - remove_proc_entry(Controller->ControllerName, DAC960_ProcDirectoryEntry); - Controller->ControllerProcEntry = NULL; -} - -#ifdef DAC960_GAM_MINOR - -static long DAC960_gam_get_controller_info(DAC960_ControllerInfo_T __user *UserSpaceControllerInfo) -{ - DAC960_ControllerInfo_T ControllerInfo; - DAC960_Controller_T *Controller; - int ControllerNumber; - long ErrorCode; - - if (UserSpaceControllerInfo == NULL) - ErrorCode = -EINVAL; - else ErrorCode = get_user(ControllerNumber, - &UserSpaceControllerInfo->ControllerNumber); - if (ErrorCode != 0) - goto out; - ErrorCode = -ENXIO; - if (ControllerNumber < 0 || - ControllerNumber > DAC960_ControllerCount - 1) { - goto out; - } - Controller = DAC960_Controllers[ControllerNumber]; - if (Controller == NULL) - goto out; - memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T)); - ControllerInfo.ControllerNumber = ControllerNumber; - ControllerInfo.FirmwareType = Controller->FirmwareType; - ControllerInfo.Channels = Controller->Channels; - ControllerInfo.Targets = Controller->Targets; - ControllerInfo.PCI_Bus = Controller->Bus; - ControllerInfo.PCI_Device = Controller->Device; - ControllerInfo.PCI_Function = Controller->Function; - ControllerInfo.IRQ_Channel = Controller->IRQ_Channel; - ControllerInfo.PCI_Address = Controller->PCI_Address; - strcpy(ControllerInfo.ModelName, Controller->ModelName); - strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion); - ErrorCode = (copy_to_user(UserSpaceControllerInfo, &ControllerInfo, - sizeof(DAC960_ControllerInfo_T)) ? -EFAULT : 0); -out: - return ErrorCode; -} - -static long DAC960_gam_v1_execute_command(DAC960_V1_UserCommand_T __user *UserSpaceUserCommand) -{ - DAC960_V1_UserCommand_T UserCommand; - DAC960_Controller_T *Controller; - DAC960_Command_T *Command = NULL; - DAC960_V1_CommandOpcode_T CommandOpcode; - DAC960_V1_CommandStatus_T CommandStatus; - DAC960_V1_DCDB_T DCDB; - DAC960_V1_DCDB_T *DCDB_IOBUF = NULL; - dma_addr_t DCDB_IOBUFDMA; - unsigned long flags; - int ControllerNumber, DataTransferLength; - unsigned char *DataTransferBuffer = NULL; - dma_addr_t DataTransferBufferDMA; - long ErrorCode; - - if (UserSpaceUserCommand == NULL) { - ErrorCode = -EINVAL; - goto out; - } - if (copy_from_user(&UserCommand, UserSpaceUserCommand, - sizeof(DAC960_V1_UserCommand_T))) { - ErrorCode = -EFAULT; - goto out; - } - ControllerNumber = UserCommand.ControllerNumber; - ErrorCode = -ENXIO; - if (ControllerNumber < 0 || - ControllerNumber > DAC960_ControllerCount - 1) - goto out; - Controller = DAC960_Controllers[ControllerNumber]; - if (Controller == NULL) - goto out; - ErrorCode = -EINVAL; - if (Controller->FirmwareType != DAC960_V1_Controller) - goto out; - CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode; - DataTransferLength = UserCommand.DataTransferLength; - if (CommandOpcode & 0x80) - goto out; - if (CommandOpcode == DAC960_V1_DCDB) - { - if (copy_from_user(&DCDB, UserCommand.DCDB, - sizeof(DAC960_V1_DCDB_T))) { - ErrorCode = -EFAULT; - goto out; - } - if (DCDB.Channel >= DAC960_V1_MaxChannels) - goto out; - if (!((DataTransferLength == 0 && - DCDB.Direction - == DAC960_V1_DCDB_NoDataTransfer) || - (DataTransferLength > 0 && - DCDB.Direction - == DAC960_V1_DCDB_DataTransferDeviceToSystem) || - (DataTransferLength < 0 && - DCDB.Direction - == DAC960_V1_DCDB_DataTransferSystemToDevice))) - goto out; - if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength) - != abs(DataTransferLength)) - goto out; - DCDB_IOBUF = pci_alloc_consistent(Controller->PCIDevice, - sizeof(DAC960_V1_DCDB_T), &DCDB_IOBUFDMA); - if (DCDB_IOBUF == NULL) { - ErrorCode = -ENOMEM; - goto out; - } - } - ErrorCode = -ENOMEM; - if (DataTransferLength > 0) - { - DataTransferBuffer = pci_zalloc_consistent(Controller->PCIDevice, - DataTransferLength, - &DataTransferBufferDMA); - if (DataTransferBuffer == NULL) - goto out; - } - else if (DataTransferLength < 0) - { - DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, - -DataTransferLength, &DataTransferBufferDMA); - if (DataTransferBuffer == NULL) - goto out; - if (copy_from_user(DataTransferBuffer, - UserCommand.DataTransferBuffer, - -DataTransferLength)) { - ErrorCode = -EFAULT; - goto out; - } - } - if (CommandOpcode == DAC960_V1_DCDB) - { - spin_lock_irqsave(&Controller->queue_lock, flags); - while ((Command = DAC960_AllocateCommand(Controller)) == NULL) - DAC960_WaitForCommand(Controller); - while (Controller->V1.DirectCommandActive[DCDB.Channel] - [DCDB.TargetID]) - { - spin_unlock_irq(&Controller->queue_lock); - __wait_event(Controller->CommandWaitQueue, - !Controller->V1.DirectCommandActive - [DCDB.Channel][DCDB.TargetID]); - spin_lock_irq(&Controller->queue_lock); - } - Controller->V1.DirectCommandActive[DCDB.Channel] - [DCDB.TargetID] = true; - spin_unlock_irqrestore(&Controller->queue_lock, flags); - DAC960_V1_ClearCommand(Command); - Command->CommandType = DAC960_ImmediateCommand; - memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox, - sizeof(DAC960_V1_CommandMailbox_T)); - Command->V1.CommandMailbox.Type3.BusAddress = DCDB_IOBUFDMA; - DCDB.BusAddress = DataTransferBufferDMA; - memcpy(DCDB_IOBUF, &DCDB, sizeof(DAC960_V1_DCDB_T)); - } - else - { - spin_lock_irqsave(&Controller->queue_lock, flags); - while ((Command = DAC960_AllocateCommand(Controller)) == NULL) - DAC960_WaitForCommand(Controller); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - DAC960_V1_ClearCommand(Command); - Command->CommandType = DAC960_ImmediateCommand; - memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox, - sizeof(DAC960_V1_CommandMailbox_T)); - if (DataTransferBuffer != NULL) - Command->V1.CommandMailbox.Type3.BusAddress = - DataTransferBufferDMA; - } - DAC960_ExecuteCommand(Command); - CommandStatus = Command->V1.CommandStatus; - spin_lock_irqsave(&Controller->queue_lock, flags); - DAC960_DeallocateCommand(Command); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - if (DataTransferLength > 0) - { - if (copy_to_user(UserCommand.DataTransferBuffer, - DataTransferBuffer, DataTransferLength)) { - ErrorCode = -EFAULT; - goto Failure1; - } - } - if (CommandOpcode == DAC960_V1_DCDB) - { - /* - I don't believe Target or Channel in the DCDB_IOBUF - should be any different from the contents of DCDB. - */ - Controller->V1.DirectCommandActive[DCDB.Channel] - [DCDB.TargetID] = false; - if (copy_to_user(UserCommand.DCDB, DCDB_IOBUF, - sizeof(DAC960_V1_DCDB_T))) { - ErrorCode = -EFAULT; - goto Failure1; - } - } - ErrorCode = CommandStatus; - Failure1: - if (DataTransferBuffer != NULL) - pci_free_consistent(Controller->PCIDevice, abs(DataTransferLength), - DataTransferBuffer, DataTransferBufferDMA); - if (DCDB_IOBUF != NULL) - pci_free_consistent(Controller->PCIDevice, sizeof(DAC960_V1_DCDB_T), - DCDB_IOBUF, DCDB_IOBUFDMA); - out: - return ErrorCode; -} - -static long DAC960_gam_v2_execute_command(DAC960_V2_UserCommand_T __user *UserSpaceUserCommand) -{ - DAC960_V2_UserCommand_T UserCommand; - DAC960_Controller_T *Controller; - DAC960_Command_T *Command = NULL; - DAC960_V2_CommandMailbox_T *CommandMailbox; - DAC960_V2_CommandStatus_T CommandStatus; - unsigned long flags; - int ControllerNumber, DataTransferLength; - int DataTransferResidue, RequestSenseLength; - unsigned char *DataTransferBuffer = NULL; - dma_addr_t DataTransferBufferDMA; - unsigned char *RequestSenseBuffer = NULL; - dma_addr_t RequestSenseBufferDMA; - long ErrorCode = -EINVAL; - - if (UserSpaceUserCommand == NULL) - goto out; - if (copy_from_user(&UserCommand, UserSpaceUserCommand, - sizeof(DAC960_V2_UserCommand_T))) { - ErrorCode = -EFAULT; - goto out; - } - ErrorCode = -ENXIO; - ControllerNumber = UserCommand.ControllerNumber; - if (ControllerNumber < 0 || - ControllerNumber > DAC960_ControllerCount - 1) - goto out; - Controller = DAC960_Controllers[ControllerNumber]; - if (Controller == NULL) - goto out; - if (Controller->FirmwareType != DAC960_V2_Controller){ - ErrorCode = -EINVAL; - goto out; - } - DataTransferLength = UserCommand.DataTransferLength; - ErrorCode = -ENOMEM; - if (DataTransferLength > 0) - { - DataTransferBuffer = pci_zalloc_consistent(Controller->PCIDevice, - DataTransferLength, - &DataTransferBufferDMA); - if (DataTransferBuffer == NULL) - goto out; - } - else if (DataTransferLength < 0) - { - DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, - -DataTransferLength, &DataTransferBufferDMA); - if (DataTransferBuffer == NULL) - goto out; - if (copy_from_user(DataTransferBuffer, - UserCommand.DataTransferBuffer, - -DataTransferLength)) { - ErrorCode = -EFAULT; - goto Failure2; - } - } - RequestSenseLength = UserCommand.RequestSenseLength; - if (RequestSenseLength > 0) - { - RequestSenseBuffer = pci_zalloc_consistent(Controller->PCIDevice, - RequestSenseLength, - &RequestSenseBufferDMA); - if (RequestSenseBuffer == NULL) - { - ErrorCode = -ENOMEM; - goto Failure2; - } - } - spin_lock_irqsave(&Controller->queue_lock, flags); - while ((Command = DAC960_AllocateCommand(Controller)) == NULL) - DAC960_WaitForCommand(Controller); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - DAC960_V2_ClearCommand(Command); - Command->CommandType = DAC960_ImmediateCommand; - CommandMailbox = &Command->V2.CommandMailbox; - memcpy(CommandMailbox, &UserCommand.CommandMailbox, - sizeof(DAC960_V2_CommandMailbox_T)); - CommandMailbox->Common.CommandControlBits - .AdditionalScatterGatherListMemory = false; - CommandMailbox->Common.CommandControlBits - .NoAutoRequestSense = true; - CommandMailbox->Common.DataTransferSize = 0; - CommandMailbox->Common.DataTransferPageNumber = 0; - memset(&CommandMailbox->Common.DataTransferMemoryAddress, 0, - sizeof(DAC960_V2_DataTransferMemoryAddress_T)); - if (DataTransferLength != 0) - { - if (DataTransferLength > 0) - { - CommandMailbox->Common.CommandControlBits - .DataTransferControllerToHost = true; - CommandMailbox->Common.DataTransferSize = DataTransferLength; - } - else - { - CommandMailbox->Common.CommandControlBits - .DataTransferControllerToHost = false; - CommandMailbox->Common.DataTransferSize = -DataTransferLength; - } - CommandMailbox->Common.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentDataPointer = DataTransferBufferDMA; - CommandMailbox->Common.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentByteCount = - CommandMailbox->Common.DataTransferSize; - } - if (RequestSenseLength > 0) - { - CommandMailbox->Common.CommandControlBits - .NoAutoRequestSense = false; - CommandMailbox->Common.RequestSenseSize = RequestSenseLength; - CommandMailbox->Common.RequestSenseBusAddress = - RequestSenseBufferDMA; - } - DAC960_ExecuteCommand(Command); - CommandStatus = Command->V2.CommandStatus; - RequestSenseLength = Command->V2.RequestSenseLength; - DataTransferResidue = Command->V2.DataTransferResidue; - spin_lock_irqsave(&Controller->queue_lock, flags); - DAC960_DeallocateCommand(Command); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - if (RequestSenseLength > UserCommand.RequestSenseLength) - RequestSenseLength = UserCommand.RequestSenseLength; - if (copy_to_user(&UserSpaceUserCommand->DataTransferLength, - &DataTransferResidue, - sizeof(DataTransferResidue))) { - ErrorCode = -EFAULT; - goto Failure2; - } - if (copy_to_user(&UserSpaceUserCommand->RequestSenseLength, - &RequestSenseLength, sizeof(RequestSenseLength))) { - ErrorCode = -EFAULT; - goto Failure2; - } - if (DataTransferLength > 0) - { - if (copy_to_user(UserCommand.DataTransferBuffer, - DataTransferBuffer, DataTransferLength)) { - ErrorCode = -EFAULT; - goto Failure2; - } - } - if (RequestSenseLength > 0) - { - if (copy_to_user(UserCommand.RequestSenseBuffer, - RequestSenseBuffer, RequestSenseLength)) { - ErrorCode = -EFAULT; - goto Failure2; - } - } - ErrorCode = CommandStatus; - Failure2: - pci_free_consistent(Controller->PCIDevice, abs(DataTransferLength), - DataTransferBuffer, DataTransferBufferDMA); - if (RequestSenseBuffer != NULL) - pci_free_consistent(Controller->PCIDevice, RequestSenseLength, - RequestSenseBuffer, RequestSenseBufferDMA); -out: - return ErrorCode; -} - -static long DAC960_gam_v2_get_health_status(DAC960_V2_GetHealthStatus_T __user *UserSpaceGetHealthStatus) -{ - DAC960_V2_GetHealthStatus_T GetHealthStatus; - DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer; - DAC960_Controller_T *Controller; - int ControllerNumber; - long ErrorCode; - - if (UserSpaceGetHealthStatus == NULL) { - ErrorCode = -EINVAL; - goto out; - } - if (copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus, - sizeof(DAC960_V2_GetHealthStatus_T))) { - ErrorCode = -EFAULT; - goto out; - } - ErrorCode = -ENXIO; - ControllerNumber = GetHealthStatus.ControllerNumber; - if (ControllerNumber < 0 || - ControllerNumber > DAC960_ControllerCount - 1) - goto out; - Controller = DAC960_Controllers[ControllerNumber]; - if (Controller == NULL) - goto out; - if (Controller->FirmwareType != DAC960_V2_Controller) { - ErrorCode = -EINVAL; - goto out; - } - if (copy_from_user(&HealthStatusBuffer, - GetHealthStatus.HealthStatusBuffer, - sizeof(DAC960_V2_HealthStatusBuffer_T))) { - ErrorCode = -EFAULT; - goto out; - } - ErrorCode = wait_event_interruptible_timeout(Controller->HealthStatusWaitQueue, - !(Controller->V2.HealthStatusBuffer->StatusChangeCounter - == HealthStatusBuffer.StatusChangeCounter && - Controller->V2.HealthStatusBuffer->NextEventSequenceNumber - == HealthStatusBuffer.NextEventSequenceNumber), - DAC960_MonitoringTimerInterval); - if (ErrorCode == -ERESTARTSYS) { - ErrorCode = -EINTR; - goto out; - } - if (copy_to_user(GetHealthStatus.HealthStatusBuffer, - Controller->V2.HealthStatusBuffer, - sizeof(DAC960_V2_HealthStatusBuffer_T))) - ErrorCode = -EFAULT; - else - ErrorCode = 0; - -out: - return ErrorCode; -} - -/* - * DAC960_gam_ioctl is the ioctl function for performing RAID operations. -*/ - -static long DAC960_gam_ioctl(struct file *file, unsigned int Request, - unsigned long Argument) -{ - long ErrorCode = 0; - void __user *argp = (void __user *)Argument; - if (!capable(CAP_SYS_ADMIN)) return -EACCES; - - mutex_lock(&DAC960_mutex); - switch (Request) - { - case DAC960_IOCTL_GET_CONTROLLER_COUNT: - ErrorCode = DAC960_ControllerCount; - break; - case DAC960_IOCTL_GET_CONTROLLER_INFO: - ErrorCode = DAC960_gam_get_controller_info(argp); - break; - case DAC960_IOCTL_V1_EXECUTE_COMMAND: - ErrorCode = DAC960_gam_v1_execute_command(argp); - break; - case DAC960_IOCTL_V2_EXECUTE_COMMAND: - ErrorCode = DAC960_gam_v2_execute_command(argp); - break; - case DAC960_IOCTL_V2_GET_HEALTH_STATUS: - ErrorCode = DAC960_gam_v2_get_health_status(argp); - break; - default: - ErrorCode = -ENOTTY; - } - mutex_unlock(&DAC960_mutex); - return ErrorCode; -} - -static const struct file_operations DAC960_gam_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = DAC960_gam_ioctl, - .llseek = noop_llseek, -}; - -static struct miscdevice DAC960_gam_dev = { - DAC960_GAM_MINOR, - "dac960_gam", - &DAC960_gam_fops -}; - -static int DAC960_gam_init(void) -{ - int ret; - - ret = misc_register(&DAC960_gam_dev); - if (ret) - printk(KERN_ERR "DAC960_gam: can't misc_register on minor %d\n", DAC960_GAM_MINOR); - return ret; -} - -static void DAC960_gam_cleanup(void) -{ - misc_deregister(&DAC960_gam_dev); -} - -#endif /* DAC960_GAM_MINOR */ - -static struct DAC960_privdata DAC960_GEM_privdata = { - .HardwareType = DAC960_GEM_Controller, - .FirmwareType = DAC960_V2_Controller, - .InterruptHandler = DAC960_GEM_InterruptHandler, - .MemoryWindowSize = DAC960_GEM_RegisterWindowSize, -}; - - -static struct DAC960_privdata DAC960_BA_privdata = { - .HardwareType = DAC960_BA_Controller, - .FirmwareType = DAC960_V2_Controller, - .InterruptHandler = DAC960_BA_InterruptHandler, - .MemoryWindowSize = DAC960_BA_RegisterWindowSize, -}; - -static struct DAC960_privdata DAC960_LP_privdata = { - .HardwareType = DAC960_LP_Controller, - .FirmwareType = DAC960_V2_Controller, - .InterruptHandler = DAC960_LP_InterruptHandler, - .MemoryWindowSize = DAC960_LP_RegisterWindowSize, -}; - -static struct DAC960_privdata DAC960_LA_privdata = { - .HardwareType = DAC960_LA_Controller, - .FirmwareType = DAC960_V1_Controller, - .InterruptHandler = DAC960_LA_InterruptHandler, - .MemoryWindowSize = DAC960_LA_RegisterWindowSize, -}; - -static struct DAC960_privdata DAC960_PG_privdata = { - .HardwareType = DAC960_PG_Controller, - .FirmwareType = DAC960_V1_Controller, - .InterruptHandler = DAC960_PG_InterruptHandler, - .MemoryWindowSize = DAC960_PG_RegisterWindowSize, -}; - -static struct DAC960_privdata DAC960_PD_privdata = { - .HardwareType = DAC960_PD_Controller, - .FirmwareType = DAC960_V1_Controller, - .InterruptHandler = DAC960_PD_InterruptHandler, - .MemoryWindowSize = DAC960_PD_RegisterWindowSize, -}; - -static struct DAC960_privdata DAC960_P_privdata = { - .HardwareType = DAC960_P_Controller, - .FirmwareType = DAC960_V1_Controller, - .InterruptHandler = DAC960_P_InterruptHandler, - .MemoryWindowSize = DAC960_PD_RegisterWindowSize, -}; - -static const struct pci_device_id DAC960_id_table[] = { - { - .vendor = PCI_VENDOR_ID_MYLEX, - .device = PCI_DEVICE_ID_MYLEX_DAC960_GEM, - .subvendor = PCI_VENDOR_ID_MYLEX, - .subdevice = PCI_ANY_ID, - .driver_data = (unsigned long) &DAC960_GEM_privdata, - }, - { - .vendor = PCI_VENDOR_ID_MYLEX, - .device = PCI_DEVICE_ID_MYLEX_DAC960_BA, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = (unsigned long) &DAC960_BA_privdata, - }, - { - .vendor = PCI_VENDOR_ID_MYLEX, - .device = PCI_DEVICE_ID_MYLEX_DAC960_LP, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = (unsigned long) &DAC960_LP_privdata, - }, - { - .vendor = PCI_VENDOR_ID_DEC, - .device = PCI_DEVICE_ID_DEC_21285, - .subvendor = PCI_VENDOR_ID_MYLEX, - .subdevice = PCI_DEVICE_ID_MYLEX_DAC960_LA, - .driver_data = (unsigned long) &DAC960_LA_privdata, - }, - { - .vendor = PCI_VENDOR_ID_MYLEX, - .device = PCI_DEVICE_ID_MYLEX_DAC960_PG, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = (unsigned long) &DAC960_PG_privdata, - }, - { - .vendor = PCI_VENDOR_ID_MYLEX, - .device = PCI_DEVICE_ID_MYLEX_DAC960_PD, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = (unsigned long) &DAC960_PD_privdata, - }, - { - .vendor = PCI_VENDOR_ID_MYLEX, - .device = PCI_DEVICE_ID_MYLEX_DAC960_P, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = (unsigned long) &DAC960_P_privdata, - }, - {0, }, -}; - -MODULE_DEVICE_TABLE(pci, DAC960_id_table); - -static struct pci_driver DAC960_pci_driver = { - .name = "DAC960", - .id_table = DAC960_id_table, - .probe = DAC960_Probe, - .remove = DAC960_Remove, -}; - -static int __init DAC960_init_module(void) -{ - int ret; - - ret = pci_register_driver(&DAC960_pci_driver); -#ifdef DAC960_GAM_MINOR - if (!ret) - DAC960_gam_init(); -#endif - return ret; -} - -static void __exit DAC960_cleanup_module(void) -{ - int i; - -#ifdef DAC960_GAM_MINOR - DAC960_gam_cleanup(); -#endif - - for (i = 0; i < DAC960_ControllerCount; i++) { - DAC960_Controller_T *Controller = DAC960_Controllers[i]; - if (Controller == NULL) - continue; - DAC960_FinalizeController(Controller); - } - if (DAC960_ProcDirectoryEntry != NULL) { - remove_proc_entry("rd/status", NULL); - remove_proc_entry("rd", NULL); - } - DAC960_ControllerCount = 0; - pci_unregister_driver(&DAC960_pci_driver); -} - -module_init(DAC960_init_module); -module_exit(DAC960_cleanup_module); - -MODULE_LICENSE("GPL"); diff --git a/drivers/block/DAC960.h b/drivers/block/DAC960.h deleted file mode 100644 index 1439e651928b..000000000000 --- a/drivers/block/DAC960.h +++ /dev/null @@ -1,4414 +0,0 @@ -/* - - Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers - - Copyright 1998-2001 by Leonard N. Zubkoff - - This program is free software; you may redistribute and/or modify it under - the terms of the GNU General Public License Version 2 as published by the - Free Software Foundation. - - 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 complete details. - - The author respectfully requests that any modifications to this software be - sent directly to him for evaluation and testing. - -*/ - - -/* - Define the maximum number of DAC960 Controllers supported by this driver. -*/ - -#define DAC960_MaxControllers 8 - - -/* - Define the maximum number of Controller Channels supported by DAC960 - V1 and V2 Firmware Controllers. -*/ - -#define DAC960_V1_MaxChannels 3 -#define DAC960_V2_MaxChannels 4 - - -/* - Define the maximum number of Targets per Channel supported by DAC960 - V1 and V2 Firmware Controllers. -*/ - -#define DAC960_V1_MaxTargets 16 -#define DAC960_V2_MaxTargets 128 - - -/* - Define the maximum number of Logical Drives supported by DAC960 - V1 and V2 Firmware Controllers. -*/ - -#define DAC960_MaxLogicalDrives 32 - - -/* - Define the maximum number of Physical Devices supported by DAC960 - V1 and V2 Firmware Controllers. -*/ - -#define DAC960_V1_MaxPhysicalDevices 45 -#define DAC960_V2_MaxPhysicalDevices 272 - -/* - Define a 32/64 bit I/O Address data type. -*/ - -typedef unsigned long DAC960_IO_Address_T; - - -/* - Define a 32/64 bit PCI Bus Address data type. -*/ - -typedef unsigned long DAC960_PCI_Address_T; - - -/* - Define a 32 bit Bus Address data type. -*/ - -typedef unsigned int DAC960_BusAddress32_T; - - -/* - Define a 64 bit Bus Address data type. -*/ - -typedef unsigned long long DAC960_BusAddress64_T; - - -/* - Define a 32 bit Byte Count data type. -*/ - -typedef unsigned int DAC960_ByteCount32_T; - - -/* - Define a 64 bit Byte Count data type. -*/ - -typedef unsigned long long DAC960_ByteCount64_T; - - -/* - dma_loaf is used by helper routines to divide a region of - dma mapped memory into smaller pieces, where those pieces - are not of uniform size. - */ - -struct dma_loaf { - void *cpu_base; - dma_addr_t dma_base; - size_t length; - void *cpu_free; - dma_addr_t dma_free; -}; - -/* - Define the SCSI INQUIRY Standard Data structure. -*/ - -typedef struct DAC960_SCSI_Inquiry -{ - unsigned char PeripheralDeviceType:5; /* Byte 0 Bits 0-4 */ - unsigned char PeripheralQualifier:3; /* Byte 0 Bits 5-7 */ - unsigned char DeviceTypeModifier:7; /* Byte 1 Bits 0-6 */ - bool RMB:1; /* Byte 1 Bit 7 */ - unsigned char ANSI_ApprovedVersion:3; /* Byte 2 Bits 0-2 */ - unsigned char ECMA_Version:3; /* Byte 2 Bits 3-5 */ - unsigned char ISO_Version:2; /* Byte 2 Bits 6-7 */ - unsigned char ResponseDataFormat:4; /* Byte 3 Bits 0-3 */ - unsigned char :2; /* Byte 3 Bits 4-5 */ - bool TrmIOP:1; /* Byte 3 Bit 6 */ - bool AENC:1; /* Byte 3 Bit 7 */ - unsigned char AdditionalLength; /* Byte 4 */ - unsigned char :8; /* Byte 5 */ - unsigned char :8; /* Byte 6 */ - bool SftRe:1; /* Byte 7 Bit 0 */ - bool CmdQue:1; /* Byte 7 Bit 1 */ - bool :1; /* Byte 7 Bit 2 */ - bool Linked:1; /* Byte 7 Bit 3 */ - bool Sync:1; /* Byte 7 Bit 4 */ - bool WBus16:1; /* Byte 7 Bit 5 */ - bool WBus32:1; /* Byte 7 Bit 6 */ - bool RelAdr:1; /* Byte 7 Bit 7 */ - unsigned char VendorIdentification[8]; /* Bytes 8-15 */ - unsigned char ProductIdentification[16]; /* Bytes 16-31 */ - unsigned char ProductRevisionLevel[4]; /* Bytes 32-35 */ -} -DAC960_SCSI_Inquiry_T; - - -/* - Define the SCSI INQUIRY Unit Serial Number structure. -*/ - -typedef struct DAC960_SCSI_Inquiry_UnitSerialNumber -{ - unsigned char PeripheralDeviceType:5; /* Byte 0 Bits 0-4 */ - unsigned char PeripheralQualifier:3; /* Byte 0 Bits 5-7 */ - unsigned char PageCode; /* Byte 1 */ - unsigned char :8; /* Byte 2 */ - unsigned char PageLength; /* Byte 3 */ - unsigned char ProductSerialNumber[28]; /* Bytes 4-31 */ -} -DAC960_SCSI_Inquiry_UnitSerialNumber_T; - - -/* - Define the SCSI REQUEST SENSE Sense Key type. -*/ - -typedef enum -{ - DAC960_SenseKey_NoSense = 0x0, - DAC960_SenseKey_RecoveredError = 0x1, - DAC960_SenseKey_NotReady = 0x2, - DAC960_SenseKey_MediumError = 0x3, - DAC960_SenseKey_HardwareError = 0x4, - DAC960_SenseKey_IllegalRequest = 0x5, - DAC960_SenseKey_UnitAttention = 0x6, - DAC960_SenseKey_DataProtect = 0x7, - DAC960_SenseKey_BlankCheck = 0x8, - DAC960_SenseKey_VendorSpecific = 0x9, - DAC960_SenseKey_CopyAborted = 0xA, - DAC960_SenseKey_AbortedCommand = 0xB, - DAC960_SenseKey_Equal = 0xC, - DAC960_SenseKey_VolumeOverflow = 0xD, - DAC960_SenseKey_Miscompare = 0xE, - DAC960_SenseKey_Reserved = 0xF -} -__attribute__ ((packed)) -DAC960_SCSI_RequestSenseKey_T; - - -/* - Define the SCSI REQUEST SENSE structure. -*/ - -typedef struct DAC960_SCSI_RequestSense -{ - unsigned char ErrorCode:7; /* Byte 0 Bits 0-6 */ - bool Valid:1; /* Byte 0 Bit 7 */ - unsigned char SegmentNumber; /* Byte 1 */ - DAC960_SCSI_RequestSenseKey_T SenseKey:4; /* Byte 2 Bits 0-3 */ - unsigned char :1; /* Byte 2 Bit 4 */ - bool ILI:1; /* Byte 2 Bit 5 */ - bool EOM:1; /* Byte 2 Bit 6 */ - bool Filemark:1; /* Byte 2 Bit 7 */ - unsigned char Information[4]; /* Bytes 3-6 */ - unsigned char AdditionalSenseLength; /* Byte 7 */ - unsigned char CommandSpecificInformation[4]; /* Bytes 8-11 */ - unsigned char AdditionalSenseCode; /* Byte 12 */ - unsigned char AdditionalSenseCodeQualifier; /* Byte 13 */ -} -DAC960_SCSI_RequestSense_T; - - -/* - Define the DAC960 V1 Firmware Command Opcodes. -*/ - -typedef enum -{ - /* I/O Commands */ - DAC960_V1_ReadExtended = 0x33, - DAC960_V1_WriteExtended = 0x34, - DAC960_V1_ReadAheadExtended = 0x35, - DAC960_V1_ReadExtendedWithScatterGather = 0xB3, - DAC960_V1_WriteExtendedWithScatterGather = 0xB4, - DAC960_V1_Read = 0x36, - DAC960_V1_ReadWithScatterGather = 0xB6, - DAC960_V1_Write = 0x37, - DAC960_V1_WriteWithScatterGather = 0xB7, - DAC960_V1_DCDB = 0x04, - DAC960_V1_DCDBWithScatterGather = 0x84, - DAC960_V1_Flush = 0x0A, - /* Controller Status Related Commands */ - DAC960_V1_Enquiry = 0x53, - DAC960_V1_Enquiry2 = 0x1C, - DAC960_V1_GetLogicalDriveElement = 0x55, - DAC960_V1_GetLogicalDriveInformation = 0x19, - DAC960_V1_IOPortRead = 0x39, - DAC960_V1_IOPortWrite = 0x3A, - DAC960_V1_GetSDStats = 0x3E, - DAC960_V1_GetPDStats = 0x3F, - DAC960_V1_PerformEventLogOperation = 0x72, - /* Device Related Commands */ - DAC960_V1_StartDevice = 0x10, - DAC960_V1_GetDeviceState = 0x50, - DAC960_V1_StopChannel = 0x13, - DAC960_V1_StartChannel = 0x12, - DAC960_V1_ResetChannel = 0x1A, - /* Commands Associated with Data Consistency and Errors */ - DAC960_V1_Rebuild = 0x09, - DAC960_V1_RebuildAsync = 0x16, - DAC960_V1_CheckConsistency = 0x0F, - DAC960_V1_CheckConsistencyAsync = 0x1E, - DAC960_V1_RebuildStat = 0x0C, - DAC960_V1_GetRebuildProgress = 0x27, - DAC960_V1_RebuildControl = 0x1F, - DAC960_V1_ReadBadBlockTable = 0x0B, - DAC960_V1_ReadBadDataTable = 0x25, - DAC960_V1_ClearBadDataTable = 0x26, - DAC960_V1_GetErrorTable = 0x17, - DAC960_V1_AddCapacityAsync = 0x2A, - DAC960_V1_BackgroundInitializationControl = 0x2B, - /* Configuration Related Commands */ - DAC960_V1_ReadConfig2 = 0x3D, - DAC960_V1_WriteConfig2 = 0x3C, - DAC960_V1_ReadConfigurationOnDisk = 0x4A, - DAC960_V1_WriteConfigurationOnDisk = 0x4B, - DAC960_V1_ReadConfiguration = 0x4E, - DAC960_V1_ReadBackupConfiguration = 0x4D, - DAC960_V1_WriteConfiguration = 0x4F, - DAC960_V1_AddConfiguration = 0x4C, - DAC960_V1_ReadConfigurationLabel = 0x48, - DAC960_V1_WriteConfigurationLabel = 0x49, - /* Firmware Upgrade Related Commands */ - DAC960_V1_LoadImage = 0x20, - DAC960_V1_StoreImage = 0x21, - DAC960_V1_ProgramImage = 0x22, - /* Diagnostic Commands */ - DAC960_V1_SetDiagnosticMode = 0x31, - DAC960_V1_RunDiagnostic = 0x32, - /* Subsystem Service Commands */ - DAC960_V1_GetSubsystemData = 0x70, - DAC960_V1_SetSubsystemParameters = 0x71, - /* Version 2.xx Firmware Commands */ - DAC960_V1_Enquiry_Old = 0x05, - DAC960_V1_GetDeviceState_Old = 0x14, - DAC960_V1_Read_Old = 0x02, - DAC960_V1_Write_Old = 0x03, - DAC960_V1_ReadWithScatterGather_Old = 0x82, - DAC960_V1_WriteWithScatterGather_Old = 0x83 -} -__attribute__ ((packed)) -DAC960_V1_CommandOpcode_T; - - -/* - Define the DAC960 V1 Firmware Command Identifier type. -*/ - -typedef unsigned char DAC960_V1_CommandIdentifier_T; - - -/* - Define the DAC960 V1 Firmware Command Status Codes. -*/ - -#define DAC960_V1_NormalCompletion 0x0000 /* Common */ -#define DAC960_V1_CheckConditionReceived 0x0002 /* Common */ -#define DAC960_V1_NoDeviceAtAddress 0x0102 /* Common */ -#define DAC960_V1_InvalidDeviceAddress 0x0105 /* Common */ -#define DAC960_V1_InvalidParameter 0x0105 /* Common */ -#define DAC960_V1_IrrecoverableDataError 0x0001 /* I/O */ -#define DAC960_V1_LogicalDriveNonexistentOrOffline 0x0002 /* I/O */ -#define DAC960_V1_AccessBeyondEndOfLogicalDrive 0x0105 /* I/O */ -#define DAC960_V1_BadDataEncountered 0x010C /* I/O */ -#define DAC960_V1_DeviceBusy 0x0008 /* DCDB */ -#define DAC960_V1_DeviceNonresponsive 0x000E /* DCDB */ -#define DAC960_V1_CommandTerminatedAbnormally 0x000F /* DCDB */ -#define DAC960_V1_UnableToStartDevice 0x0002 /* Device */ -#define DAC960_V1_InvalidChannelOrTargetOrModifier 0x0105 /* Device */ -#define DAC960_V1_ChannelBusy 0x0106 /* Device */ -#define DAC960_V1_ChannelNotStopped 0x0002 /* Device */ -#define DAC960_V1_AttemptToRebuildOnlineDrive 0x0002 /* Consistency */ -#define DAC960_V1_RebuildBadBlocksEncountered 0x0003 /* Consistency */ -#define DAC960_V1_NewDiskFailedDuringRebuild 0x0004 /* Consistency */ -#define DAC960_V1_RebuildOrCheckAlreadyInProgress 0x0106 /* Consistency */ -#define DAC960_V1_DependentDiskIsDead 0x0002 /* Consistency */ -#define DAC960_V1_InconsistentBlocksFound 0x0003 /* Consistency */ -#define DAC960_V1_InvalidOrNonredundantLogicalDrive 0x0105 /* Consistency */ -#define DAC960_V1_NoRebuildOrCheckInProgress 0x0105 /* Consistency */ -#define DAC960_V1_RebuildInProgress_DataValid 0x0000 /* Consistency */ -#define DAC960_V1_RebuildFailed_LogicalDriveFailure 0x0002 /* Consistency */ -#define DAC960_V1_RebuildFailed_BadBlocksOnOther 0x0003 /* Consistency */ -#define DAC960_V1_RebuildFailed_NewDriveFailed 0x0004 /* Consistency */ -#define DAC960_V1_RebuildSuccessful 0x0100 /* Consistency */ -#define DAC960_V1_RebuildSuccessfullyTerminated 0x0107 /* Consistency */ -#define DAC960_V1_BackgroundInitSuccessful 0x0100 /* Consistency */ -#define DAC960_V1_BackgroundInitAborted 0x0005 /* Consistency */ -#define DAC960_V1_NoBackgroundInitInProgress 0x0105 /* Consistency */ -#define DAC960_V1_AddCapacityInProgress 0x0004 /* Consistency */ -#define DAC960_V1_AddCapacityFailedOrSuspended 0x00F4 /* Consistency */ -#define DAC960_V1_Config2ChecksumError 0x0002 /* Configuration */ -#define DAC960_V1_ConfigurationSuspended 0x0106 /* Configuration */ -#define DAC960_V1_FailedToConfigureNVRAM 0x0105 /* Configuration */ -#define DAC960_V1_ConfigurationNotSavedStateChange 0x0106 /* Configuration */ -#define DAC960_V1_SubsystemNotInstalled 0x0001 /* Subsystem */ -#define DAC960_V1_SubsystemFailed 0x0002 /* Subsystem */ -#define DAC960_V1_SubsystemBusy 0x0106 /* Subsystem */ - -typedef unsigned short DAC960_V1_CommandStatus_T; - - -/* - Define the DAC960 V1 Firmware Enquiry Command reply structure. -*/ - -typedef struct DAC960_V1_Enquiry -{ - unsigned char NumberOfLogicalDrives; /* Byte 0 */ - unsigned int :24; /* Bytes 1-3 */ - unsigned int LogicalDriveSizes[32]; /* Bytes 4-131 */ - unsigned short FlashAge; /* Bytes 132-133 */ - struct { - bool DeferredWriteError:1; /* Byte 134 Bit 0 */ - bool BatteryLow:1; /* Byte 134 Bit 1 */ - unsigned char :6; /* Byte 134 Bits 2-7 */ - } StatusFlags; - unsigned char :8; /* Byte 135 */ - unsigned char MinorFirmwareVersion; /* Byte 136 */ - unsigned char MajorFirmwareVersion; /* Byte 137 */ - enum { - DAC960_V1_NoStandbyRebuildOrCheckInProgress = 0x00, - DAC960_V1_StandbyRebuildInProgress = 0x01, - DAC960_V1_BackgroundRebuildInProgress = 0x02, - DAC960_V1_BackgroundCheckInProgress = 0x03, - DAC960_V1_StandbyRebuildCompletedWithError = 0xFF, - DAC960_V1_BackgroundRebuildOrCheckFailed_DriveFailed = 0xF0, - DAC960_V1_BackgroundRebuildOrCheckFailed_LogicalDriveFailed = 0xF1, - DAC960_V1_BackgroundRebuildOrCheckFailed_OtherCauses = 0xF2, - DAC960_V1_BackgroundRebuildOrCheckSuccessfullyTerminated = 0xF3 - } __attribute__ ((packed)) RebuildFlag; /* Byte 138 */ - unsigned char MaxCommands; /* Byte 139 */ - unsigned char OfflineLogicalDriveCount; /* Byte 140 */ - unsigned char :8; /* Byte 141 */ - unsigned short EventLogSequenceNumber; /* Bytes 142-143 */ - unsigned char CriticalLogicalDriveCount; /* Byte 144 */ - unsigned int :24; /* Bytes 145-147 */ - unsigned char DeadDriveCount; /* Byte 148 */ - unsigned char :8; /* Byte 149 */ - unsigned char RebuildCount; /* Byte 150 */ - struct { - unsigned char :3; /* Byte 151 Bits 0-2 */ - bool BatteryBackupUnitPresent:1; /* Byte 151 Bit 3 */ - unsigned char :3; /* Byte 151 Bits 4-6 */ - unsigned char :1; /* Byte 151 Bit 7 */ - } MiscFlags; - struct { - unsigned char TargetID; - unsigned char Channel; - } DeadDrives[21]; /* Bytes 152-194 */ - unsigned char Reserved[62]; /* Bytes 195-255 */ -} -__attribute__ ((packed)) -DAC960_V1_Enquiry_T; - - -/* - Define the DAC960 V1 Firmware Enquiry2 Command reply structure. -*/ - -typedef struct DAC960_V1_Enquiry2 -{ - struct { - enum { - DAC960_V1_P_PD_PU = 0x01, - DAC960_V1_PL = 0x02, - DAC960_V1_PG = 0x10, - DAC960_V1_PJ = 0x11, - DAC960_V1_PR = 0x12, - DAC960_V1_PT = 0x13, - DAC960_V1_PTL0 = 0x14, - DAC960_V1_PRL = 0x15, - DAC960_V1_PTL1 = 0x16, - DAC960_V1_1164P = 0x20 - } __attribute__ ((packed)) SubModel; /* Byte 0 */ - unsigned char ActualChannels; /* Byte 1 */ - enum { - DAC960_V1_FiveChannelBoard = 0x01, - DAC960_V1_ThreeChannelBoard = 0x02, - DAC960_V1_TwoChannelBoard = 0x03, - DAC960_V1_ThreeChannelASIC_DAC = 0x04 - } __attribute__ ((packed)) Model; /* Byte 2 */ - enum { - DAC960_V1_EISA_Controller = 0x01, - DAC960_V1_MicroChannel_Controller = 0x02, - DAC960_V1_PCI_Controller = 0x03, - DAC960_V1_SCSItoSCSI_Controller = 0x08 - } __attribute__ ((packed)) ProductFamily; /* Byte 3 */ - } HardwareID; /* Bytes 0-3 */ - /* MajorVersion.MinorVersion-FirmwareType-TurnID */ - struct { - unsigned char MajorVersion; /* Byte 4 */ - unsigned char MinorVersion; /* Byte 5 */ - unsigned char TurnID; /* Byte 6 */ - char FirmwareType; /* Byte 7 */ - } FirmwareID; /* Bytes 4-7 */ - unsigned char :8; /* Byte 8 */ - unsigned int :24; /* Bytes 9-11 */ - unsigned char ConfiguredChannels; /* Byte 12 */ - unsigned char ActualChannels; /* Byte 13 */ - unsigned char MaxTargets; /* Byte 14 */ - unsigned char MaxTags; /* Byte 15 */ - unsigned char MaxLogicalDrives; /* Byte 16 */ - unsigned char MaxArms; /* Byte 17 */ - unsigned char MaxSpans; /* Byte 18 */ - unsigned char :8; /* Byte 19 */ - unsigned int :32; /* Bytes 20-23 */ - unsigned int MemorySize; /* Bytes 24-27 */ - unsigned int CacheSize; /* Bytes 28-31 */ - unsigned int FlashMemorySize; /* Bytes 32-35 */ - unsigned int NonVolatileMemorySize; /* Bytes 36-39 */ - struct { - enum { - DAC960_V1_RamType_DRAM = 0x0, - DAC960_V1_RamType_EDO = 0x1, - DAC960_V1_RamType_SDRAM = 0x2, - DAC960_V1_RamType_Last = 0x7 - } __attribute__ ((packed)) RamType:3; /* Byte 40 Bits 0-2 */ - enum { - DAC960_V1_ErrorCorrection_None = 0x0, - DAC960_V1_ErrorCorrection_Parity = 0x1, - DAC960_V1_ErrorCorrection_ECC = 0x2, - DAC960_V1_ErrorCorrection_Last = 0x7 - } __attribute__ ((packed)) ErrorCorrection:3; /* Byte 40 Bits 3-5 */ - bool FastPageMode:1; /* Byte 40 Bit 6 */ - bool LowPowerMemory:1; /* Byte 40 Bit 7 */ - unsigned char :8; /* Bytes 41 */ - } MemoryType; - unsigned short ClockSpeed; /* Bytes 42-43 */ - unsigned short MemorySpeed; /* Bytes 44-45 */ - unsigned short HardwareSpeed; /* Bytes 46-47 */ - unsigned int :32; /* Bytes 48-51 */ - unsigned int :32; /* Bytes 52-55 */ - unsigned char :8; /* Byte 56 */ - unsigned char :8; /* Byte 57 */ - unsigned short :16; /* Bytes 58-59 */ - unsigned short MaxCommands; /* Bytes 60-61 */ - unsigned short MaxScatterGatherEntries; /* Bytes 62-63 */ - unsigned short MaxDriveCommands; /* Bytes 64-65 */ - unsigned short MaxIODescriptors; /* Bytes 66-67 */ - unsigned short MaxCombinedSectors; /* Bytes 68-69 */ - unsigned char Latency; /* Byte 70 */ - unsigned char :8; /* Byte 71 */ - unsigned char SCSITimeout; /* Byte 72 */ - unsigned char :8; /* Byte 73 */ - unsigned short MinFreeLines; /* Bytes 74-75 */ - unsigned int :32; /* Bytes 76-79 */ - unsigned int :32; /* Bytes 80-83 */ - unsigned char RebuildRateConstant; /* Byte 84 */ - unsigned char :8; /* Byte 85 */ - unsigned char :8; /* Byte 86 */ - unsigned char :8; /* Byte 87 */ - unsigned int :32; /* Bytes 88-91 */ - unsigned int :32; /* Bytes 92-95 */ - unsigned short PhysicalDriveBlockSize; /* Bytes 96-97 */ - unsigned short LogicalDriveBlockSize; /* Bytes 98-99 */ - unsigned short MaxBlocksPerCommand; /* Bytes 100-101 */ - unsigned short BlockFactor; /* Bytes 102-103 */ - unsigned short CacheLineSize; /* Bytes 104-105 */ - struct { - enum { - DAC960_V1_Narrow_8bit = 0x0, - DAC960_V1_Wide_16bit = 0x1, - DAC960_V1_Wide_32bit = 0x2 - } __attribute__ ((packed)) BusWidth:2; /* Byte 106 Bits 0-1 */ - enum { - DAC960_V1_Fast = 0x0, - DAC960_V1_Ultra = 0x1, - DAC960_V1_Ultra2 = 0x2 - } __attribute__ ((packed)) BusSpeed:2; /* Byte 106 Bits 2-3 */ - bool Differential:1; /* Byte 106 Bit 4 */ - unsigned char :3; /* Byte 106 Bits 5-7 */ - } SCSICapability; - unsigned char :8; /* Byte 107 */ - unsigned int :32; /* Bytes 108-111 */ - unsigned short FirmwareBuildNumber; /* Bytes 112-113 */ - enum { - DAC960_V1_AEMI = 0x01, - DAC960_V1_OEM1 = 0x02, - DAC960_V1_OEM2 = 0x04, - DAC960_V1_OEM3 = 0x08, - DAC960_V1_Conner = 0x10, - DAC960_V1_SAFTE = 0x20 - } __attribute__ ((packed)) FaultManagementType; /* Byte 114 */ - unsigned char :8; /* Byte 115 */ - struct { - bool Clustering:1; /* Byte 116 Bit 0 */ - bool MylexOnlineRAIDExpansion:1; /* Byte 116 Bit 1 */ - bool ReadAhead:1; /* Byte 116 Bit 2 */ - bool BackgroundInitialization:1; /* Byte 116 Bit 3 */ - unsigned int :28; /* Bytes 116-119 */ - } FirmwareFeatures; - unsigned int :32; /* Bytes 120-123 */ - unsigned int :32; /* Bytes 124-127 */ -} -DAC960_V1_Enquiry2_T; - - -/* - Define the DAC960 V1 Firmware Logical Drive State type. -*/ - -typedef enum -{ - DAC960_V1_LogicalDrive_Online = 0x03, - DAC960_V1_LogicalDrive_Critical = 0x04, - DAC960_V1_LogicalDrive_Offline = 0xFF -} -__attribute__ ((packed)) -DAC960_V1_LogicalDriveState_T; - - -/* - Define the DAC960 V1 Firmware Logical Drive Information structure. -*/ - -typedef struct DAC960_V1_LogicalDriveInformation -{ - unsigned int LogicalDriveSize; /* Bytes 0-3 */ - DAC960_V1_LogicalDriveState_T LogicalDriveState; /* Byte 4 */ - unsigned char RAIDLevel:7; /* Byte 5 Bits 0-6 */ - bool WriteBack:1; /* Byte 5 Bit 7 */ - unsigned short :16; /* Bytes 6-7 */ -} -DAC960_V1_LogicalDriveInformation_T; - - -/* - Define the DAC960 V1 Firmware Get Logical Drive Information Command - reply structure. -*/ - -typedef DAC960_V1_LogicalDriveInformation_T - DAC960_V1_LogicalDriveInformationArray_T[DAC960_MaxLogicalDrives]; - - -/* - Define the DAC960 V1 Firmware Perform Event Log Operation Types. -*/ - -typedef enum -{ - DAC960_V1_GetEventLogEntry = 0x00 -} -__attribute__ ((packed)) -DAC960_V1_PerformEventLogOpType_T; - - -/* - Define the DAC960 V1 Firmware Get Event Log Entry Command reply structure. -*/ - -typedef struct DAC960_V1_EventLogEntry -{ - unsigned char MessageType; /* Byte 0 */ - unsigned char MessageLength; /* Byte 1 */ - unsigned char TargetID:5; /* Byte 2 Bits 0-4 */ - unsigned char Channel:3; /* Byte 2 Bits 5-7 */ - unsigned char LogicalUnit:6; /* Byte 3 Bits 0-5 */ - unsigned char :2; /* Byte 3 Bits 6-7 */ - unsigned short SequenceNumber; /* Bytes 4-5 */ - unsigned char ErrorCode:7; /* Byte 6 Bits 0-6 */ - bool Valid:1; /* Byte 6 Bit 7 */ - unsigned char SegmentNumber; /* Byte 7 */ - DAC960_SCSI_RequestSenseKey_T SenseKey:4; /* Byte 8 Bits 0-3 */ - unsigned char :1; /* Byte 8 Bit 4 */ - bool ILI:1; /* Byte 8 Bit 5 */ - bool EOM:1; /* Byte 8 Bit 6 */ - bool Filemark:1; /* Byte 8 Bit 7 */ - unsigned char Information[4]; /* Bytes 9-12 */ - unsigned char AdditionalSenseLength; /* Byte 13 */ - unsigned char CommandSpecificInformation[4]; /* Bytes 14-17 */ - unsigned char AdditionalSenseCode; /* Byte 18 */ - unsigned char AdditionalSenseCodeQualifier; /* Byte 19 */ - unsigned char Dummy[12]; /* Bytes 20-31 */ -} -DAC960_V1_EventLogEntry_T; - - -/* - Define the DAC960 V1 Firmware Physical Device State type. -*/ - -typedef enum -{ - DAC960_V1_Device_Dead = 0x00, - DAC960_V1_Device_WriteOnly = 0x02, - DAC960_V1_Device_Online = 0x03, - DAC960_V1_Device_Standby = 0x10 -} -__attribute__ ((packed)) -DAC960_V1_PhysicalDeviceState_T; - - -/* - Define the DAC960 V1 Firmware Get Device State Command reply structure. - The structure is padded by 2 bytes for compatibility with Version 2.xx - Firmware. -*/ - -typedef struct DAC960_V1_DeviceState -{ - bool Present:1; /* Byte 0 Bit 0 */ - unsigned char :7; /* Byte 0 Bits 1-7 */ - enum { - DAC960_V1_OtherType = 0x0, - DAC960_V1_DiskType = 0x1, - DAC960_V1_SequentialType = 0x2, - DAC960_V1_CDROM_or_WORM_Type = 0x3 - } __attribute__ ((packed)) DeviceType:2; /* Byte 1 Bits 0-1 */ - bool :1; /* Byte 1 Bit 2 */ - bool Fast20:1; /* Byte 1 Bit 3 */ - bool Sync:1; /* Byte 1 Bit 4 */ - bool Fast:1; /* Byte 1 Bit 5 */ - bool Wide:1; /* Byte 1 Bit 6 */ - bool TaggedQueuingSupported:1; /* Byte 1 Bit 7 */ - DAC960_V1_PhysicalDeviceState_T DeviceState; /* Byte 2 */ - unsigned char :8; /* Byte 3 */ - unsigned char SynchronousMultiplier; /* Byte 4 */ - unsigned char SynchronousOffset:5; /* Byte 5 Bits 0-4 */ - unsigned char :3; /* Byte 5 Bits 5-7 */ - unsigned int DiskSize __attribute__ ((packed)); /* Bytes 6-9 */ - unsigned short :16; /* Bytes 10-11 */ -} -DAC960_V1_DeviceState_T; - - -/* - Define the DAC960 V1 Firmware Get Rebuild Progress Command reply structure. -*/ - -typedef struct DAC960_V1_RebuildProgress -{ - unsigned int LogicalDriveNumber; /* Bytes 0-3 */ - unsigned int LogicalDriveSize; /* Bytes 4-7 */ - unsigned int RemainingBlocks; /* Bytes 8-11 */ -} -DAC960_V1_RebuildProgress_T; - - -/* - Define the DAC960 V1 Firmware Background Initialization Status Command - reply structure. -*/ - -typedef struct DAC960_V1_BackgroundInitializationStatus -{ - unsigned int LogicalDriveSize; /* Bytes 0-3 */ - unsigned int BlocksCompleted; /* Bytes 4-7 */ - unsigned char Reserved1[12]; /* Bytes 8-19 */ - unsigned int LogicalDriveNumber; /* Bytes 20-23 */ - unsigned char RAIDLevel; /* Byte 24 */ - enum { - DAC960_V1_BackgroundInitializationInvalid = 0x00, - DAC960_V1_BackgroundInitializationStarted = 0x02, - DAC960_V1_BackgroundInitializationInProgress = 0x04, - DAC960_V1_BackgroundInitializationSuspended = 0x05, - DAC960_V1_BackgroundInitializationCancelled = 0x06 - } __attribute__ ((packed)) Status; /* Byte 25 */ - unsigned char Reserved2[6]; /* Bytes 26-31 */ -} -DAC960_V1_BackgroundInitializationStatus_T; - - -/* - Define the DAC960 V1 Firmware Error Table Entry structure. -*/ - -typedef struct DAC960_V1_ErrorTableEntry -{ - unsigned char ParityErrorCount; /* Byte 0 */ - unsigned char SoftErrorCount; /* Byte 1 */ - unsigned char HardErrorCount; /* Byte 2 */ - unsigned char MiscErrorCount; /* Byte 3 */ -} -DAC960_V1_ErrorTableEntry_T; - - -/* - Define the DAC960 V1 Firmware Get Error Table Command reply structure. -*/ - -typedef struct DAC960_V1_ErrorTable -{ - DAC960_V1_ErrorTableEntry_T - ErrorTableEntries[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets]; -} -DAC960_V1_ErrorTable_T; - - -/* - Define the DAC960 V1 Firmware Read Config2 Command reply structure. -*/ - -typedef struct DAC960_V1_Config2 -{ - unsigned char :1; /* Byte 0 Bit 0 */ - bool ActiveNegationEnabled:1; /* Byte 0 Bit 1 */ - unsigned char :5; /* Byte 0 Bits 2-6 */ - bool NoRescanIfResetReceivedDuringScan:1; /* Byte 0 Bit 7 */ - bool StorageWorksSupportEnabled:1; /* Byte 1 Bit 0 */ - bool HewlettPackardSupportEnabled:1; /* Byte 1 Bit 1 */ - bool NoDisconnectOnFirstCommand:1; /* Byte 1 Bit 2 */ - unsigned char :2; /* Byte 1 Bits 3-4 */ - bool AEMI_ARM:1; /* Byte 1 Bit 5 */ - bool AEMI_OFM:1; /* Byte 1 Bit 6 */ - unsigned char :1; /* Byte 1 Bit 7 */ - enum { - DAC960_V1_OEMID_Mylex = 0x00, - DAC960_V1_OEMID_IBM = 0x08, - DAC960_V1_OEMID_HP = 0x0A, - DAC960_V1_OEMID_DEC = 0x0C, - DAC960_V1_OEMID_Siemens = 0x10, - DAC960_V1_OEMID_Intel = 0x12 - } __attribute__ ((packed)) OEMID; /* Byte 2 */ - unsigned char OEMModelNumber; /* Byte 3 */ - unsigned char PhysicalSector; /* Byte 4 */ - unsigned char LogicalSector; /* Byte 5 */ - unsigned char BlockFactor; /* Byte 6 */ - bool ReadAheadEnabled:1; /* Byte 7 Bit 0 */ - bool LowBIOSDelay:1; /* Byte 7 Bit 1 */ - unsigned char :2; /* Byte 7 Bits 2-3 */ - bool ReassignRestrictedToOneSector:1; /* Byte 7 Bit 4 */ - unsigned char :1; /* Byte 7 Bit 5 */ - bool ForceUnitAccessDuringWriteRecovery:1; /* Byte 7 Bit 6 */ - bool EnableLeftSymmetricRAID5Algorithm:1; /* Byte 7 Bit 7 */ - unsigned char DefaultRebuildRate; /* Byte 8 */ - unsigned char :8; /* Byte 9 */ - unsigned char BlocksPerCacheLine; /* Byte 10 */ - unsigned char BlocksPerStripe; /* Byte 11 */ - struct { - enum { - DAC960_V1_Async = 0x0, - DAC960_V1_Sync_8MHz = 0x1, - DAC960_V1_Sync_5MHz = 0x2, - DAC960_V1_Sync_10or20MHz = 0x3 /* Byte 11 Bits 0-1 */ - } __attribute__ ((packed)) Speed:2; - bool Force8Bit:1; /* Byte 11 Bit 2 */ - bool DisableFast20:1; /* Byte 11 Bit 3 */ - unsigned char :3; /* Byte 11 Bits 4-6 */ - bool EnableTaggedQueuing:1; /* Byte 11 Bit 7 */ - } __attribute__ ((packed)) ChannelParameters[6]; /* Bytes 12-17 */ - unsigned char SCSIInitiatorID; /* Byte 18 */ - unsigned char :8; /* Byte 19 */ - enum { - DAC960_V1_StartupMode_ControllerSpinUp = 0x00, - DAC960_V1_StartupMode_PowerOnSpinUp = 0x01 - } __attribute__ ((packed)) StartupMode; /* Byte 20 */ - unsigned char SimultaneousDeviceSpinUpCount; /* Byte 21 */ - unsigned char SecondsDelayBetweenSpinUps; /* Byte 22 */ - unsigned char Reserved1[29]; /* Bytes 23-51 */ - bool BIOSDisabled:1; /* Byte 52 Bit 0 */ - bool CDROMBootEnabled:1; /* Byte 52 Bit 1 */ - unsigned char :3; /* Byte 52 Bits 2-4 */ - enum { - DAC960_V1_Geometry_128_32 = 0x0, - DAC960_V1_Geometry_255_63 = 0x1, - DAC960_V1_Geometry_Reserved1 = 0x2, - DAC960_V1_Geometry_Reserved2 = 0x3 - } __attribute__ ((packed)) DriveGeometry:2; /* Byte 52 Bits 5-6 */ - unsigned char :1; /* Byte 52 Bit 7 */ - unsigned char Reserved2[9]; /* Bytes 53-61 */ - unsigned short Checksum; /* Bytes 62-63 */ -} -DAC960_V1_Config2_T; - - -/* - Define the DAC960 V1 Firmware DCDB request structure. -*/ - -typedef struct DAC960_V1_DCDB -{ - unsigned char TargetID:4; /* Byte 0 Bits 0-3 */ - unsigned char Channel:4; /* Byte 0 Bits 4-7 */ - enum { - DAC960_V1_DCDB_NoDataTransfer = 0, - DAC960_V1_DCDB_DataTransferDeviceToSystem = 1, - DAC960_V1_DCDB_DataTransferSystemToDevice = 2, - DAC960_V1_DCDB_IllegalDataTransfer = 3 - } __attribute__ ((packed)) Direction:2; /* Byte 1 Bits 0-1 */ - bool EarlyStatus:1; /* Byte 1 Bit 2 */ - unsigned char :1; /* Byte 1 Bit 3 */ - enum { - DAC960_V1_DCDB_Timeout_24_hours = 0, - DAC960_V1_DCDB_Timeout_10_seconds = 1, - DAC960_V1_DCDB_Timeout_60_seconds = 2, - DAC960_V1_DCDB_Timeout_10_minutes = 3 - } __attribute__ ((packed)) Timeout:2; /* Byte 1 Bits 4-5 */ - bool NoAutomaticRequestSense:1; /* Byte 1 Bit 6 */ - bool DisconnectPermitted:1; /* Byte 1 Bit 7 */ - unsigned short TransferLength; /* Bytes 2-3 */ - DAC960_BusAddress32_T BusAddress; /* Bytes 4-7 */ - unsigned char CDBLength:4; /* Byte 8 Bits 0-3 */ - unsigned char TransferLengthHigh4:4; /* Byte 8 Bits 4-7 */ - unsigned char SenseLength; /* Byte 9 */ - unsigned char CDB[12]; /* Bytes 10-21 */ - unsigned char SenseData[64]; /* Bytes 22-85 */ - unsigned char Status; /* Byte 86 */ - unsigned char :8; /* Byte 87 */ -} -DAC960_V1_DCDB_T; - - -/* - Define the DAC960 V1 Firmware Scatter/Gather List Type 1 32 Bit Address - 32 Bit Byte Count structure. -*/ - -typedef struct DAC960_V1_ScatterGatherSegment -{ - DAC960_BusAddress32_T SegmentDataPointer; /* Bytes 0-3 */ - DAC960_ByteCount32_T SegmentByteCount; /* Bytes 4-7 */ -} -DAC960_V1_ScatterGatherSegment_T; - - -/* - Define the 13 Byte DAC960 V1 Firmware Command Mailbox structure. Bytes 13-15 - are not used. The Command Mailbox structure is padded to 16 bytes for - efficient access. -*/ - -typedef union DAC960_V1_CommandMailbox -{ - unsigned int Words[4]; /* Words 0-3 */ - unsigned char Bytes[16]; /* Bytes 0-15 */ - struct { - DAC960_V1_CommandOpcode_T CommandOpcode; /* Byte 0 */ - DAC960_V1_CommandIdentifier_T CommandIdentifier; /* Byte 1 */ - unsigned char Dummy[14]; /* Bytes 2-15 */ - } __attribute__ ((packed)) Common; - struct { - DAC960_V1_CommandOpcode_T CommandOpcode; /* Byte 0 */ - DAC960_V1_CommandIdentifier_T CommandIdentifier; /* Byte 1 */ - unsigned char Dummy1[6]; /* Bytes 2-7 */ - DAC960_BusAddress32_T BusAddress; /* Bytes 8-11 */ - unsigned char Dummy2[4]; /* Bytes 12-15 */ - } __attribute__ ((packed)) Type3; - struct { - DAC960_V1_CommandOpcode_T CommandOpcode; /* Byte 0 */ - DAC960_V1_CommandIdentifier_T CommandIdentifier; /* Byte 1 */ - unsigned char CommandOpcode2; /* Byte 2 */ - unsigned char Dummy1[5]; /* Bytes 3-7 */ - DAC960_BusAddress32_T BusAddress; /* Bytes 8-11 */ - unsigned char Dummy2[4]; /* Bytes 12-15 */ - } __attribute__ ((packed)) Type3B; - struct { - DAC960_V1_CommandOpcode_T CommandOpcode; /* Byte 0 */ - DAC960_V1_CommandIdentifier_T CommandIdentifier; /* Byte 1 */ - unsigned char Dummy1[5]; /* Bytes 2-6 */ - unsigned char LogicalDriveNumber:6; /* Byte 7 Bits 0-6 */ - bool AutoRestore:1; /* Byte 7 Bit 7 */ - unsigned char Dummy2[8]; /* Bytes 8-15 */ - } __attribute__ ((packed)) Type3C; - struct { - DAC960_V1_CommandOpcode_T CommandOpcode; /* Byte 0 */ - DAC960_V1_CommandIdentifier_T CommandIdentifier; /* Byte 1 */ - unsigned char Channel; /* Byte 2 */ - unsigned char TargetID; /* Byte 3 */ - DAC960_V1_PhysicalDeviceState_T DeviceState:5; /* Byte 4 Bits 0-4 */ - unsigned char Modifier:3; /* Byte 4 Bits 5-7 */ - unsigned char Dummy1[3]; /* Bytes 5-7 */ - DAC960_BusAddress32_T BusAddress; /* Bytes 8-11 */ - unsigned char Dummy2[4]; /* Bytes 12-15 */ - } __attribute__ ((packed)) Type3D; - struct { - DAC960_V1_CommandOpcode_T CommandOpcode; /* Byte 0 */ - DAC960_V1_CommandIdentifier_T CommandIdentifier; /* Byte 1 */ - DAC960_V1_PerformEventLogOpType_T OperationType; /* Byte 2 */ - unsigned char OperationQualifier; /* Byte 3 */ - unsigned short SequenceNumber; /* Bytes 4-5 */ - unsigned char Dummy1[2]; /* Bytes 6-7 */ - DAC960_BusAddress32_T BusAddress; /* Bytes 8-11 */ - unsigned char Dummy2[4]; /* Bytes 12-15 */ - } __attribute__ ((packed)) Type3E; - struct { - DAC960_V1_CommandOpcode_T CommandOpcode; /* Byte 0 */ - DAC960_V1_CommandIdentifier_T CommandIdentifier; /* Byte 1 */ - unsigned char Dummy1[2]; /* Bytes 2-3 */ - unsigned char RebuildRateConstant; /* Byte 4 */ - unsigned char Dummy2[3]; /* Bytes 5-7 */ - DAC960_BusAddress32_T BusAddress; /* Bytes 8-11 */ - unsigned char Dummy3[4]; /* Bytes 12-15 */ - } __attribute__ ((packed)) Type3R; - struct { - DAC960_V1_CommandOpcode_T CommandOpcode; /* Byte 0 */ - DAC960_V1_CommandIdentifier_T CommandIdentifier; /* Byte 1 */ - unsigned short TransferLength; /* Bytes 2-3 */ - unsigned int LogicalBlockAddress; /* Bytes 4-7 */ - DAC960_BusAddress32_T BusAddress; /* Bytes 8-11 */ - unsigned char LogicalDriveNumber; /* Byte 12 */ - unsigned char Dummy[3]; /* Bytes 13-15 */ - } __attribute__ ((packed)) Type4; - struct { - DAC960_V1_CommandOpcode_T CommandOpcode; /* Byte 0 */ - DAC960_V1_CommandIdentifier_T CommandIdentifier; /* Byte 1 */ - struct { - unsigned short TransferLength:11; /* Bytes 2-3 */ - unsigned char LogicalDriveNumber:5; /* Byte 3 Bits 3-7 */ - } __attribute__ ((packed)) LD; - unsigned int LogicalBlockAddress; /* Bytes 4-7 */ - DAC960_BusAddress32_T BusAddress; /* Bytes 8-11 */ - unsigned char ScatterGatherCount:6; /* Byte 12 Bits 0-5 */ - enum { - DAC960_V1_ScatterGather_32BitAddress_32BitByteCount = 0x0, - DAC960_V1_ScatterGather_32BitAddress_16BitByteCount = 0x1, - DAC960_V1_ScatterGather_32BitByteCount_32BitAddress = 0x2, - DAC960_V1_ScatterGather_16BitByteCount_32BitAddress = 0x3 - } __attribute__ ((packed)) ScatterGatherType:2; /* Byte 12 Bits 6-7 */ - unsigned char Dummy[3]; /* Bytes 13-15 */ - } __attribute__ ((packed)) Type5; - struct { - DAC960_V1_CommandOpcode_T CommandOpcode; /* Byte 0 */ - DAC960_V1_CommandIdentifier_T CommandIdentifier; /* Byte 1 */ - unsigned char CommandOpcode2; /* Byte 2 */ - unsigned char :8; /* Byte 3 */ - DAC960_BusAddress32_T CommandMailboxesBusAddress; /* Bytes 4-7 */ - DAC960_BusAddress32_T StatusMailboxesBusAddress; /* Bytes 8-11 */ - unsigned char Dummy[4]; /* Bytes 12-15 */ - } __attribute__ ((packed)) TypeX; -} -DAC960_V1_CommandMailbox_T; - - -/* - Define the DAC960 V2 Firmware Command Opcodes. -*/ - -typedef enum -{ - DAC960_V2_MemCopy = 0x01, - DAC960_V2_SCSI_10_Passthru = 0x02, - DAC960_V2_SCSI_255_Passthru = 0x03, - DAC960_V2_SCSI_10 = 0x04, - DAC960_V2_SCSI_256 = 0x05, - DAC960_V2_IOCTL = 0x20 -} -__attribute__ ((packed)) -DAC960_V2_CommandOpcode_T; - - -/* - Define the DAC960 V2 Firmware IOCTL Opcodes. -*/ - -typedef enum -{ - DAC960_V2_GetControllerInfo = 0x01, - DAC960_V2_GetLogicalDeviceInfoValid = 0x03, - DAC960_V2_GetPhysicalDeviceInfoValid = 0x05, - DAC960_V2_GetHealthStatus = 0x11, - DAC960_V2_GetEvent = 0x15, - DAC960_V2_StartDiscovery = 0x81, - DAC960_V2_SetDeviceState = 0x82, - DAC960_V2_RebuildDeviceStart = 0x88, - DAC960_V2_RebuildDeviceStop = 0x89, - DAC960_V2_ConsistencyCheckStart = 0x8C, - DAC960_V2_ConsistencyCheckStop = 0x8D, - DAC960_V2_SetMemoryMailbox = 0x8E, - DAC960_V2_PauseDevice = 0x92, - DAC960_V2_TranslatePhysicalToLogicalDevice = 0xC5 -} -__attribute__ ((packed)) -DAC960_V2_IOCTL_Opcode_T; - - -/* - Define the DAC960 V2 Firmware Command Identifier type. -*/ - -typedef unsigned short DAC960_V2_CommandIdentifier_T; - - -/* - Define the DAC960 V2 Firmware Command Status Codes. -*/ - -#define DAC960_V2_NormalCompletion 0x00 -#define DAC960_V2_AbormalCompletion 0x02 -#define DAC960_V2_DeviceBusy 0x08 -#define DAC960_V2_DeviceNonresponsive 0x0E -#define DAC960_V2_DeviceNonresponsive2 0x0F -#define DAC960_V2_DeviceRevervationConflict 0x18 - -typedef unsigned char DAC960_V2_CommandStatus_T; - - -/* - Define the DAC960 V2 Firmware Memory Type structure. -*/ - -typedef struct DAC960_V2_MemoryType -{ - enum { - DAC960_V2_MemoryType_Reserved = 0x00, - DAC960_V2_MemoryType_DRAM = 0x01, - DAC960_V2_MemoryType_EDRAM = 0x02, - DAC960_V2_MemoryType_EDO = 0x03, - DAC960_V2_MemoryType_SDRAM = 0x04, - DAC960_V2_MemoryType_Last = 0x1F - } __attribute__ ((packed)) MemoryType:5; /* Byte 0 Bits 0-4 */ - bool :1; /* Byte 0 Bit 5 */ - bool MemoryParity:1; /* Byte 0 Bit 6 */ - bool MemoryECC:1; /* Byte 0 Bit 7 */ -} -DAC960_V2_MemoryType_T; - - -/* - Define the DAC960 V2 Firmware Processor Type structure. -*/ - -typedef enum -{ - DAC960_V2_ProcessorType_i960CA = 0x01, - DAC960_V2_ProcessorType_i960RD = 0x02, - DAC960_V2_ProcessorType_i960RN = 0x03, - DAC960_V2_ProcessorType_i960RP = 0x04, - DAC960_V2_ProcessorType_NorthBay = 0x05, - DAC960_V2_ProcessorType_StrongArm = 0x06, - DAC960_V2_ProcessorType_i960RM = 0x07 -} -__attribute__ ((packed)) -DAC960_V2_ProcessorType_T; - - -/* - Define the DAC960 V2 Firmware Get Controller Info reply structure. -*/ - -typedef struct DAC960_V2_ControllerInfo -{ - unsigned char :8; /* Byte 0 */ - enum { - DAC960_V2_SCSI_Bus = 0x00, - DAC960_V2_Fibre_Bus = 0x01, - DAC960_V2_PCI_Bus = 0x03 - } __attribute__ ((packed)) BusInterfaceType; /* Byte 1 */ - enum { - DAC960_V2_DAC960E = 0x01, - DAC960_V2_DAC960M = 0x08, - DAC960_V2_DAC960PD = 0x10, - DAC960_V2_DAC960PL = 0x11, - DAC960_V2_DAC960PU = 0x12, - DAC960_V2_DAC960PE = 0x13, - DAC960_V2_DAC960PG = 0x14, - DAC960_V2_DAC960PJ = 0x15, - DAC960_V2_DAC960PTL0 = 0x16, - DAC960_V2_DAC960PR = 0x17, - DAC960_V2_DAC960PRL = 0x18, - DAC960_V2_DAC960PT = 0x19, - DAC960_V2_DAC1164P = 0x1A, - DAC960_V2_DAC960PTL1 = 0x1B, - DAC960_V2_EXR2000P = 0x1C, - DAC960_V2_EXR3000P = 0x1D, - DAC960_V2_AcceleRAID352 = 0x1E, - DAC960_V2_AcceleRAID170 = 0x1F, - DAC960_V2_AcceleRAID160 = 0x20, - DAC960_V2_DAC960S = 0x60, - DAC960_V2_DAC960SU = 0x61, - DAC960_V2_DAC960SX = 0x62, - DAC960_V2_DAC960SF = 0x63, - DAC960_V2_DAC960SS = 0x64, - DAC960_V2_DAC960FL = 0x65, - DAC960_V2_DAC960LL = 0x66, - DAC960_V2_DAC960FF = 0x67, - DAC960_V2_DAC960HP = 0x68, - DAC960_V2_RAIDBRICK = 0x69, - DAC960_V2_METEOR_FL = 0x6A, - DAC960_V2_METEOR_FF = 0x6B - } __attribute__ ((packed)) ControllerType; /* Byte 2 */ - unsigned char :8; /* Byte 3 */ - unsigned short BusInterfaceSpeedMHz; /* Bytes 4-5 */ - unsigned char BusWidthBits; /* Byte 6 */ - unsigned char FlashCodeTypeOrProductID; /* Byte 7 */ - unsigned char NumberOfHostPortsPresent; /* Byte 8 */ - unsigned char Reserved1[7]; /* Bytes 9-15 */ - unsigned char BusInterfaceName[16]; /* Bytes 16-31 */ - unsigned char ControllerName[16]; /* Bytes 32-47 */ - unsigned char Reserved2[16]; /* Bytes 48-63 */ - /* Firmware Release Information */ - unsigned char FirmwareMajorVersion; /* Byte 64 */ - unsigned char FirmwareMinorVersion; /* Byte 65 */ - unsigned char FirmwareTurnNumber; /* Byte 66 */ - unsigned char FirmwareBuildNumber; /* Byte 67 */ - unsigned char FirmwareReleaseDay; /* Byte 68 */ - unsigned char FirmwareReleaseMonth; /* Byte 69 */ - unsigned char FirmwareReleaseYearHigh2Digits; /* Byte 70 */ - unsigned char FirmwareReleaseYearLow2Digits; /* Byte 71 */ - /* Hardware Release Information */ - unsigned char HardwareRevision; /* Byte 72 */ - unsigned int :24; /* Bytes 73-75 */ - unsigned char HardwareReleaseDay; /* Byte 76 */ - unsigned char HardwareReleaseMonth; /* Byte 77 */ - unsigned char HardwareReleaseYearHigh2Digits; /* Byte 78 */ - unsigned char HardwareReleaseYearLow2Digits; /* Byte 79 */ - /* Hardware Manufacturing Information */ - unsigned char ManufacturingBatchNumber; /* Byte 80 */ - unsigned char :8; /* Byte 81 */ - unsigned char ManufacturingPlantNumber; /* Byte 82 */ - unsigned char :8; /* Byte 83 */ - unsigned char HardwareManufacturingDay; /* Byte 84 */ - unsigned char HardwareManufacturingMonth; /* Byte 85 */ - unsigned char HardwareManufacturingYearHigh2Digits; /* Byte 86 */ - unsigned char HardwareManufacturingYearLow2Digits; /* Byte 87 */ - unsigned char MaximumNumberOfPDDperXLD; /* Byte 88 */ - unsigned char MaximumNumberOfILDperXLD; /* Byte 89 */ - unsigned short NonvolatileMemorySizeKB; /* Bytes 90-91 */ - unsigned char MaximumNumberOfXLD; /* Byte 92 */ - unsigned int :24; /* Bytes 93-95 */ - /* Unique Information per Controller */ - unsigned char ControllerSerialNumber[16]; /* Bytes 96-111 */ - unsigned char Reserved3[16]; /* Bytes 112-127 */ - /* Vendor Information */ - unsigned int :24; /* Bytes 128-130 */ - unsigned char OEM_Code; /* Byte 131 */ - unsigned char VendorName[16]; /* Bytes 132-147 */ - /* Other Physical/Controller/Operation Information */ - bool BBU_Present:1; /* Byte 148 Bit 0 */ - bool ActiveActiveClusteringMode:1; /* Byte 148 Bit 1 */ - unsigned char :6; /* Byte 148 Bits 2-7 */ - unsigned char :8; /* Byte 149 */ - unsigned short :16; /* Bytes 150-151 */ - /* Physical Device Scan Information */ - bool PhysicalScanActive:1; /* Byte 152 Bit 0 */ - unsigned char :7; /* Byte 152 Bits 1-7 */ - unsigned char PhysicalDeviceChannelNumber; /* Byte 153 */ - unsigned char PhysicalDeviceTargetID; /* Byte 154 */ - unsigned char PhysicalDeviceLogicalUnit; /* Byte 155 */ - /* Maximum Command Data Transfer Sizes */ - unsigned short MaximumDataTransferSizeInBlocks; /* Bytes 156-157 */ - unsigned short MaximumScatterGatherEntries; /* Bytes 158-159 */ - /* Logical/Physical Device Counts */ - unsigned short LogicalDevicesPresent; /* Bytes 160-161 */ - unsigned short LogicalDevicesCritical; /* Bytes 162-163 */ - unsigned short LogicalDevicesOffline; /* Bytes 164-165 */ - unsigned short PhysicalDevicesPresent; /* Bytes 166-167 */ - unsigned short PhysicalDisksPresent; /* Bytes 168-169 */ - unsigned short PhysicalDisksCritical; /* Bytes 170-171 */ - unsigned short PhysicalDisksOffline; /* Bytes 172-173 */ - unsigned short MaximumParallelCommands; /* Bytes 174-175 */ - /* Channel and Target ID Information */ - unsigned char NumberOfPhysicalChannelsPresent; /* Byte 176 */ - unsigned char NumberOfVirtualChannelsPresent; /* Byte 177 */ - unsigned char NumberOfPhysicalChannelsPossible; /* Byte 178 */ - unsigned char NumberOfVirtualChannelsPossible; /* Byte 179 */ - unsigned char MaximumTargetsPerChannel[16]; /* Bytes 180-195 */ - unsigned char Reserved4[12]; /* Bytes 196-207 */ - /* Memory/Cache Information */ - unsigned short MemorySizeMB; /* Bytes 208-209 */ - unsigned short CacheSizeMB; /* Bytes 210-211 */ - unsigned int ValidCacheSizeInBytes; /* Bytes 212-215 */ - unsigned int DirtyCacheSizeInBytes; /* Bytes 216-219 */ - unsigned short MemorySpeedMHz; /* Bytes 220-221 */ - unsigned char MemoryDataWidthBits; /* Byte 222 */ - DAC960_V2_MemoryType_T MemoryType; /* Byte 223 */ - unsigned char CacheMemoryTypeName[16]; /* Bytes 224-239 */ - /* Execution Memory Information */ - unsigned short ExecutionMemorySizeMB; /* Bytes 240-241 */ - unsigned short ExecutionL2CacheSizeMB; /* Bytes 242-243 */ - unsigned char Reserved5[8]; /* Bytes 244-251 */ - unsigned short ExecutionMemorySpeedMHz; /* Bytes 252-253 */ - unsigned char ExecutionMemoryDataWidthBits; /* Byte 254 */ - DAC960_V2_MemoryType_T ExecutionMemoryType; /* Byte 255 */ - unsigned char ExecutionMemoryTypeName[16]; /* Bytes 256-271 */ - /* First CPU Type Information */ - unsigned short FirstProcessorSpeedMHz; /* Bytes 272-273 */ - DAC960_V2_ProcessorType_T FirstProcessorType; /* Byte 274 */ - unsigned char FirstProcessorCount; /* Byte 275 */ - unsigned char Reserved6[12]; /* Bytes 276-287 */ - unsigned char FirstProcessorName[16]; /* Bytes 288-303 */ - /* Second CPU Type Information */ - unsigned short SecondProcessorSpeedMHz; /* Bytes 304-305 */ - DAC960_V2_ProcessorType_T SecondProcessorType; /* Byte 306 */ - unsigned char SecondProcessorCount; /* Byte 307 */ - unsigned char Reserved7[12]; /* Bytes 308-319 */ - unsigned char SecondProcessorName[16]; /* Bytes 320-335 */ - /* Debugging/Profiling/Command Time Tracing Information */ - unsigned short CurrentProfilingDataPageNumber; /* Bytes 336-337 */ - unsigned short ProgramsAwaitingProfilingData; /* Bytes 338-339 */ - unsigned short CurrentCommandTimeTraceDataPageNumber; /* Bytes 340-341 */ - unsigned short ProgramsAwaitingCommandTimeTraceData; /* Bytes 342-343 */ - unsigned char Reserved8[8]; /* Bytes 344-351 */ - /* Error Counters on Physical Devices */ - unsigned short PhysicalDeviceBusResets; /* Bytes 352-353 */ - unsigned short PhysicalDeviceParityErrors; /* Bytes 355-355 */ - unsigned short PhysicalDeviceSoftErrors; /* Bytes 356-357 */ - unsigned short PhysicalDeviceCommandsFailed; /* Bytes 358-359 */ - unsigned short PhysicalDeviceMiscellaneousErrors; /* Bytes 360-361 */ - unsigned short PhysicalDeviceCommandTimeouts; /* Bytes 362-363 */ - unsigned short PhysicalDeviceSelectionTimeouts; /* Bytes 364-365 */ - unsigned short PhysicalDeviceRetriesDone; /* Bytes 366-367 */ - unsigned short PhysicalDeviceAbortsDone; /* Bytes 368-369 */ - unsigned short PhysicalDeviceHostCommandAbortsDone; /* Bytes 370-371 */ - unsigned short PhysicalDevicePredictedFailuresDetected; /* Bytes 372-373 */ - unsigned short PhysicalDeviceHostCommandsFailed; /* Bytes 374-375 */ - unsigned short PhysicalDeviceHardErrors; /* Bytes 376-377 */ - unsigned char Reserved9[6]; /* Bytes 378-383 */ - /* Error Counters on Logical Devices */ - unsigned short LogicalDeviceSoftErrors; /* Bytes 384-385 */ - unsigned short LogicalDeviceCommandsFailed; /* Bytes 386-387 */ - unsigned short LogicalDeviceHostCommandAbortsDone; /* Bytes 388-389 */ - unsigned short :16; /* Bytes 390-391 */ - /* Error Counters on Controller */ - unsigned short ControllerMemoryErrors; /* Bytes 392-393 */ - unsigned short ControllerHostCommandAbortsDone; /* Bytes 394-395 */ - unsigned int :32; /* Bytes 396-399 */ - /* Long Duration Activity Information */ - unsigned short BackgroundInitializationsActive; /* Bytes 400-401 */ - unsigned short LogicalDeviceInitializationsActive; /* Bytes 402-403 */ - unsigned short PhysicalDeviceInitializationsActive; /* Bytes 404-405 */ - unsigned short ConsistencyChecksActive; /* Bytes 406-407 */ - unsigned short RebuildsActive; /* Bytes 408-409 */ - unsigned short OnlineExpansionsActive; /* Bytes 410-411 */ - unsigned short PatrolActivitiesActive; /* Bytes 412-413 */ - unsigned short :16; /* Bytes 414-415 */ - /* Flash ROM Information */ - unsigned char FlashType; /* Byte 416 */ - unsigned char :8; /* Byte 417 */ - unsigned short FlashSizeMB; /* Bytes 418-419 */ - unsigned int FlashLimit; /* Bytes 420-423 */ - unsigned int FlashCount; /* Bytes 424-427 */ - unsigned int :32; /* Bytes 428-431 */ - unsigned char FlashTypeName[16]; /* Bytes 432-447 */ - /* Firmware Run Time Information */ - unsigned char RebuildRate; /* Byte 448 */ - unsigned char BackgroundInitializationRate; /* Byte 449 */ - unsigned char ForegroundInitializationRate; /* Byte 450 */ - unsigned char ConsistencyCheckRate; /* Byte 451 */ - unsigned int :32; /* Bytes 452-455 */ - unsigned int MaximumDP; /* Bytes 456-459 */ - unsigned int FreeDP; /* Bytes 460-463 */ - unsigned int MaximumIOP; /* Bytes 464-467 */ - unsigned int FreeIOP; /* Bytes 468-471 */ - unsigned short MaximumCombLengthInBlocks; /* Bytes 472-473 */ - unsigned short NumberOfConfigurationGroups; /* Bytes 474-475 */ - bool InstallationAbortStatus:1; /* Byte 476 Bit 0 */ - bool MaintenanceModeStatus:1; /* Byte 476 Bit 1 */ - unsigned int :24; /* Bytes 476-479 */ - unsigned char Reserved10[32]; /* Bytes 480-511 */ - unsigned char Reserved11[512]; /* Bytes 512-1023 */ -} -DAC960_V2_ControllerInfo_T; - - -/* - Define the DAC960 V2 Firmware Logical Device State type. -*/ - -typedef enum -{ - DAC960_V2_LogicalDevice_Online = 0x01, - DAC960_V2_LogicalDevice_Offline = 0x08, - DAC960_V2_LogicalDevice_Critical = 0x09 -} -__attribute__ ((packed)) -DAC960_V2_LogicalDeviceState_T; - - -/* - Define the DAC960 V2 Firmware Get Logical Device Info reply structure. -*/ - -typedef struct DAC960_V2_LogicalDeviceInfo -{ - unsigned char :8; /* Byte 0 */ - unsigned char Channel; /* Byte 1 */ - unsigned char TargetID; /* Byte 2 */ - unsigned char LogicalUnit; /* Byte 3 */ - DAC960_V2_LogicalDeviceState_T LogicalDeviceState; /* Byte 4 */ - unsigned char RAIDLevel; /* Byte 5 */ - unsigned char StripeSize; /* Byte 6 */ - unsigned char CacheLineSize; /* Byte 7 */ - struct { - enum { - DAC960_V2_ReadCacheDisabled = 0x0, - DAC960_V2_ReadCacheEnabled = 0x1, - DAC960_V2_ReadAheadEnabled = 0x2, - DAC960_V2_IntelligentReadAheadEnabled = 0x3, - DAC960_V2_ReadCache_Last = 0x7 - } __attribute__ ((packed)) ReadCache:3; /* Byte 8 Bits 0-2 */ - enum { - DAC960_V2_WriteCacheDisabled = 0x0, - DAC960_V2_LogicalDeviceReadOnly = 0x1, - DAC960_V2_WriteCacheEnabled = 0x2, - DAC960_V2_IntelligentWriteCacheEnabled = 0x3, - DAC960_V2_WriteCache_Last = 0x7 - } __attribute__ ((packed)) WriteCache:3; /* Byte 8 Bits 3-5 */ - bool :1; /* Byte 8 Bit 6 */ - bool LogicalDeviceInitialized:1; /* Byte 8 Bit 7 */ - } LogicalDeviceControl; /* Byte 8 */ - /* Logical Device Operations Status */ - bool ConsistencyCheckInProgress:1; /* Byte 9 Bit 0 */ - bool RebuildInProgress:1; /* Byte 9 Bit 1 */ - bool BackgroundInitializationInProgress:1; /* Byte 9 Bit 2 */ - bool ForegroundInitializationInProgress:1; /* Byte 9 Bit 3 */ - bool DataMigrationInProgress:1; /* Byte 9 Bit 4 */ - bool PatrolOperationInProgress:1; /* Byte 9 Bit 5 */ - unsigned char :2; /* Byte 9 Bits 6-7 */ - unsigned char RAID5WriteUpdate; /* Byte 10 */ - unsigned char RAID5Algorithm; /* Byte 11 */ - unsigned short LogicalDeviceNumber; /* Bytes 12-13 */ - /* BIOS Info */ - bool BIOSDisabled:1; /* Byte 14 Bit 0 */ - bool CDROMBootEnabled:1; /* Byte 14 Bit 1 */ - bool DriveCoercionEnabled:1; /* Byte 14 Bit 2 */ - bool WriteSameDisabled:1; /* Byte 14 Bit 3 */ - bool HBA_ModeEnabled:1; /* Byte 14 Bit 4 */ - enum { - DAC960_V2_Geometry_128_32 = 0x0, - DAC960_V2_Geometry_255_63 = 0x1, - DAC960_V2_Geometry_Reserved1 = 0x2, - DAC960_V2_Geometry_Reserved2 = 0x3 - } __attribute__ ((packed)) DriveGeometry:2; /* Byte 14 Bits 5-6 */ - bool SuperReadAheadEnabled:1; /* Byte 14 Bit 7 */ - unsigned char :8; /* Byte 15 */ - /* Error Counters */ - unsigned short SoftErrors; /* Bytes 16-17 */ - unsigned short CommandsFailed; /* Bytes 18-19 */ - unsigned short HostCommandAbortsDone; /* Bytes 20-21 */ - unsigned short DeferredWriteErrors; /* Bytes 22-23 */ - unsigned int :32; /* Bytes 24-27 */ - unsigned int :32; /* Bytes 28-31 */ - /* Device Size Information */ - unsigned short :16; /* Bytes 32-33 */ - unsigned short DeviceBlockSizeInBytes; /* Bytes 34-35 */ - unsigned int OriginalDeviceSize; /* Bytes 36-39 */ - unsigned int ConfigurableDeviceSize; /* Bytes 40-43 */ - unsigned int :32; /* Bytes 44-47 */ - unsigned char LogicalDeviceName[32]; /* Bytes 48-79 */ - unsigned char SCSI_InquiryData[36]; /* Bytes 80-115 */ - unsigned char Reserved1[12]; /* Bytes 116-127 */ - DAC960_ByteCount64_T LastReadBlockNumber; /* Bytes 128-135 */ - DAC960_ByteCount64_T LastWrittenBlockNumber; /* Bytes 136-143 */ - DAC960_ByteCount64_T ConsistencyCheckBlockNumber; /* Bytes 144-151 */ - DAC960_ByteCount64_T RebuildBlockNumber; /* Bytes 152-159 */ - DAC960_ByteCount64_T BackgroundInitializationBlockNumber; /* Bytes 160-167 */ - DAC960_ByteCount64_T ForegroundInitializationBlockNumber; /* Bytes 168-175 */ - DAC960_ByteCount64_T DataMigrationBlockNumber; /* Bytes 176-183 */ - DAC960_ByteCount64_T PatrolOperationBlockNumber; /* Bytes 184-191 */ - unsigned char Reserved2[64]; /* Bytes 192-255 */ -} -DAC960_V2_LogicalDeviceInfo_T; - - -/* - Define the DAC960 V2 Firmware Physical Device State type. -*/ - -typedef enum -{ - DAC960_V2_Device_Unconfigured = 0x00, - DAC960_V2_Device_Online = 0x01, - DAC960_V2_Device_Rebuild = 0x03, - DAC960_V2_Device_Missing = 0x04, - DAC960_V2_Device_Critical = 0x05, - DAC960_V2_Device_Dead = 0x08, - DAC960_V2_Device_SuspectedDead = 0x0C, - DAC960_V2_Device_CommandedOffline = 0x10, - DAC960_V2_Device_Standby = 0x21, - DAC960_V2_Device_InvalidState = 0xFF -} -__attribute__ ((packed)) -DAC960_V2_PhysicalDeviceState_T; - - -/* - Define the DAC960 V2 Firmware Get Physical Device Info reply structure. -*/ - -typedef struct DAC960_V2_PhysicalDeviceInfo -{ - unsigned char :8; /* Byte 0 */ - unsigned char Channel; /* Byte 1 */ - unsigned char TargetID; /* Byte 2 */ - unsigned char LogicalUnit; /* Byte 3 */ - /* Configuration Status Bits */ - bool PhysicalDeviceFaultTolerant:1; /* Byte 4 Bit 0 */ - bool PhysicalDeviceConnected:1; /* Byte 4 Bit 1 */ - bool PhysicalDeviceLocalToController:1; /* Byte 4 Bit 2 */ - unsigned char :5; /* Byte 4 Bits 3-7 */ - /* Multiple Host/Controller Status Bits */ - bool RemoteHostSystemDead:1; /* Byte 5 Bit 0 */ - bool RemoteControllerDead:1; /* Byte 5 Bit 1 */ - unsigned char :6; /* Byte 5 Bits 2-7 */ - DAC960_V2_PhysicalDeviceState_T PhysicalDeviceState; /* Byte 6 */ - unsigned char NegotiatedDataWidthBits; /* Byte 7 */ - unsigned short NegotiatedSynchronousMegaTransfers; /* Bytes 8-9 */ - /* Multiported Physical Device Information */ - unsigned char NumberOfPortConnections; /* Byte 10 */ - unsigned char DriveAccessibilityBitmap; /* Byte 11 */ - unsigned int :32; /* Bytes 12-15 */ - unsigned char NetworkAddress[16]; /* Bytes 16-31 */ - unsigned short MaximumTags; /* Bytes 32-33 */ - /* Physical Device Operations Status */ - bool ConsistencyCheckInProgress:1; /* Byte 34 Bit 0 */ - bool RebuildInProgress:1; /* Byte 34 Bit 1 */ - bool MakingDataConsistentInProgress:1; /* Byte 34 Bit 2 */ - bool PhysicalDeviceInitializationInProgress:1; /* Byte 34 Bit 3 */ - bool DataMigrationInProgress:1; /* Byte 34 Bit 4 */ - bool PatrolOperationInProgress:1; /* Byte 34 Bit 5 */ - unsigned char :2; /* Byte 34 Bits 6-7 */ - unsigned char LongOperationStatus; /* Byte 35 */ - unsigned char ParityErrors; /* Byte 36 */ - unsigned char SoftErrors; /* Byte 37 */ - unsigned char HardErrors; /* Byte 38 */ - unsigned char MiscellaneousErrors; /* Byte 39 */ - unsigned char CommandTimeouts; /* Byte 40 */ - unsigned char Retries; /* Byte 41 */ - unsigned char Aborts; /* Byte 42 */ - unsigned char PredictedFailuresDetected; /* Byte 43 */ - unsigned int :32; /* Bytes 44-47 */ - unsigned short :16; /* Bytes 48-49 */ - unsigned short DeviceBlockSizeInBytes; /* Bytes 50-51 */ - unsigned int OriginalDeviceSize; /* Bytes 52-55 */ - unsigned int ConfigurableDeviceSize; /* Bytes 56-59 */ - unsigned int :32; /* Bytes 60-63 */ - unsigned char PhysicalDeviceName[16]; /* Bytes 64-79 */ - unsigned char Reserved1[16]; /* Bytes 80-95 */ - unsigned char Reserved2[32]; /* Bytes 96-127 */ - unsigned char SCSI_InquiryData[36]; /* Bytes 128-163 */ - unsigned char Reserved3[20]; /* Bytes 164-183 */ - unsigned char Reserved4[8]; /* Bytes 184-191 */ - DAC960_ByteCount64_T LastReadBlockNumber; /* Bytes 192-199 */ - DAC960_ByteCount64_T LastWrittenBlockNumber; /* Bytes 200-207 */ - DAC960_ByteCount64_T ConsistencyCheckBlockNumber; /* Bytes 208-215 */ - DAC960_ByteCount64_T RebuildBlockNumber; /* Bytes 216-223 */ - DAC960_ByteCount64_T MakingDataConsistentBlockNumber; /* Bytes 224-231 */ - DAC960_ByteCount64_T DeviceInitializationBlockNumber; /* Bytes 232-239 */ - DAC960_ByteCount64_T DataMigrationBlockNumber; /* Bytes 240-247 */ - DAC960_ByteCount64_T PatrolOperationBlockNumber; /* Bytes 248-255 */ - unsigned char Reserved5[256]; /* Bytes 256-511 */ -} -DAC960_V2_PhysicalDeviceInfo_T; - - -/* - Define the DAC960 V2 Firmware Health Status Buffer structure. -*/ - -typedef struct DAC960_V2_HealthStatusBuffer -{ - unsigned int MicrosecondsFromControllerStartTime; /* Bytes 0-3 */ - unsigned int MillisecondsFromControllerStartTime; /* Bytes 4-7 */ - unsigned int SecondsFrom1January1970; /* Bytes 8-11 */ - unsigned int :32; /* Bytes 12-15 */ - unsigned int StatusChangeCounter; /* Bytes 16-19 */ - unsigned int :32; /* Bytes 20-23 */ - unsigned int DebugOutputMessageBufferIndex; /* Bytes 24-27 */ - unsigned int CodedMessageBufferIndex; /* Bytes 28-31 */ - unsigned int CurrentTimeTracePageNumber; /* Bytes 32-35 */ - unsigned int CurrentProfilerPageNumber; /* Bytes 36-39 */ - unsigned int NextEventSequenceNumber; /* Bytes 40-43 */ - unsigned int :32; /* Bytes 44-47 */ - unsigned char Reserved1[16]; /* Bytes 48-63 */ - unsigned char Reserved2[64]; /* Bytes 64-127 */ -} -DAC960_V2_HealthStatusBuffer_T; - - -/* - Define the DAC960 V2 Firmware Get Event reply structure. -*/ - -typedef struct DAC960_V2_Event -{ - unsigned int EventSequenceNumber; /* Bytes 0-3 */ - unsigned int EventTime; /* Bytes 4-7 */ - unsigned int EventCode; /* Bytes 8-11 */ - unsigned char :8; /* Byte 12 */ - unsigned char Channel; /* Byte 13 */ - unsigned char TargetID; /* Byte 14 */ - unsigned char LogicalUnit; /* Byte 15 */ - unsigned int :32; /* Bytes 16-19 */ - unsigned int EventSpecificParameter; /* Bytes 20-23 */ - unsigned char RequestSenseData[40]; /* Bytes 24-63 */ -} -DAC960_V2_Event_T; - - -/* - Define the DAC960 V2 Firmware Command Control Bits structure. -*/ - -typedef struct DAC960_V2_CommandControlBits -{ - bool ForceUnitAccess:1; /* Byte 0 Bit 0 */ - bool DisablePageOut:1; /* Byte 0 Bit 1 */ - bool :1; /* Byte 0 Bit 2 */ - bool AdditionalScatterGatherListMemory:1; /* Byte 0 Bit 3 */ - bool DataTransferControllerToHost:1; /* Byte 0 Bit 4 */ - bool :1; /* Byte 0 Bit 5 */ - bool NoAutoRequestSense:1; /* Byte 0 Bit 6 */ - bool DisconnectProhibited:1; /* Byte 0 Bit 7 */ -} -DAC960_V2_CommandControlBits_T; - - -/* - Define the DAC960 V2 Firmware Command Timeout structure. -*/ - -typedef struct DAC960_V2_CommandTimeout -{ - unsigned char TimeoutValue:6; /* Byte 0 Bits 0-5 */ - enum { - DAC960_V2_TimeoutScale_Seconds = 0, - DAC960_V2_TimeoutScale_Minutes = 1, - DAC960_V2_TimeoutScale_Hours = 2, - DAC960_V2_TimeoutScale_Reserved = 3 - } __attribute__ ((packed)) TimeoutScale:2; /* Byte 0 Bits 6-7 */ -} -DAC960_V2_CommandTimeout_T; - - -/* - Define the DAC960 V2 Firmware Physical Device structure. -*/ - -typedef struct DAC960_V2_PhysicalDevice -{ - unsigned char LogicalUnit; /* Byte 0 */ - unsigned char TargetID; /* Byte 1 */ - unsigned char Channel:3; /* Byte 2 Bits 0-2 */ - unsigned char Controller:5; /* Byte 2 Bits 3-7 */ -} -__attribute__ ((packed)) -DAC960_V2_PhysicalDevice_T; - - -/* - Define the DAC960 V2 Firmware Logical Device structure. -*/ - -typedef struct DAC960_V2_LogicalDevice -{ - unsigned short LogicalDeviceNumber; /* Bytes 0-1 */ - unsigned char :3; /* Byte 2 Bits 0-2 */ - unsigned char Controller:5; /* Byte 2 Bits 3-7 */ -} -__attribute__ ((packed)) -DAC960_V2_LogicalDevice_T; - - -/* - Define the DAC960 V2 Firmware Operation Device type. -*/ - -typedef enum -{ - DAC960_V2_Physical_Device = 0x00, - DAC960_V2_RAID_Device = 0x01, - DAC960_V2_Physical_Channel = 0x02, - DAC960_V2_RAID_Channel = 0x03, - DAC960_V2_Physical_Controller = 0x04, - DAC960_V2_RAID_Controller = 0x05, - DAC960_V2_Configuration_Group = 0x10, - DAC960_V2_Enclosure = 0x11 -} -__attribute__ ((packed)) -DAC960_V2_OperationDevice_T; - - -/* - Define the DAC960 V2 Firmware Translate Physical To Logical Device structure. -*/ - -typedef struct DAC960_V2_PhysicalToLogicalDevice -{ - unsigned short LogicalDeviceNumber; /* Bytes 0-1 */ - unsigned short :16; /* Bytes 2-3 */ - unsigned char PreviousBootController; /* Byte 4 */ - unsigned char PreviousBootChannel; /* Byte 5 */ - unsigned char PreviousBootTargetID; /* Byte 6 */ - unsigned char PreviousBootLogicalUnit; /* Byte 7 */ -} -DAC960_V2_PhysicalToLogicalDevice_T; - - - -/* - Define the DAC960 V2 Firmware Scatter/Gather List Entry structure. -*/ - -typedef struct DAC960_V2_ScatterGatherSegment -{ - DAC960_BusAddress64_T SegmentDataPointer; /* Bytes 0-7 */ - DAC960_ByteCount64_T SegmentByteCount; /* Bytes 8-15 */ -} -DAC960_V2_ScatterGatherSegment_T; - - -/* - Define the DAC960 V2 Firmware Data Transfer Memory Address structure. -*/ - -typedef union DAC960_V2_DataTransferMemoryAddress -{ - DAC960_V2_ScatterGatherSegment_T ScatterGatherSegments[2]; /* Bytes 0-31 */ - struct { - unsigned short ScatterGatherList0Length; /* Bytes 0-1 */ - unsigned short ScatterGatherList1Length; /* Bytes 2-3 */ - unsigned short ScatterGatherList2Length; /* Bytes 4-5 */ - unsigned short :16; /* Bytes 6-7 */ - DAC960_BusAddress64_T ScatterGatherList0Address; /* Bytes 8-15 */ - DAC960_BusAddress64_T ScatterGatherList1Address; /* Bytes 16-23 */ - DAC960_BusAddress64_T ScatterGatherList2Address; /* Bytes 24-31 */ - } ExtendedScatterGather; -} -DAC960_V2_DataTransferMemoryAddress_T; - - -/* - Define the 64 Byte DAC960 V2 Firmware Command Mailbox structure. -*/ - -typedef union DAC960_V2_CommandMailbox -{ - unsigned int Words[16]; /* Words 0-15 */ - struct { - DAC960_V2_CommandIdentifier_T CommandIdentifier; /* Bytes 0-1 */ - DAC960_V2_CommandOpcode_T CommandOpcode; /* Byte 2 */ - DAC960_V2_CommandControlBits_T CommandControlBits; /* Byte 3 */ - DAC960_ByteCount32_T DataTransferSize:24; /* Bytes 4-6 */ - unsigned char DataTransferPageNumber; /* Byte 7 */ - DAC960_BusAddress64_T RequestSenseBusAddress; /* Bytes 8-15 */ - unsigned int :24; /* Bytes 16-18 */ - DAC960_V2_CommandTimeout_T CommandTimeout; /* Byte 19 */ - unsigned char RequestSenseSize; /* Byte 20 */ - unsigned char IOCTL_Opcode; /* Byte 21 */ - unsigned char Reserved[10]; /* Bytes 22-31 */ - DAC960_V2_DataTransferMemoryAddress_T - DataTransferMemoryAddress; /* Bytes 32-63 */ - } Common; - struct { - DAC960_V2_CommandIdentifier_T CommandIdentifier; /* Bytes 0-1 */ - DAC960_V2_CommandOpcode_T CommandOpcode; /* Byte 2 */ - DAC960_V2_CommandControlBits_T CommandControlBits; /* Byte 3 */ - DAC960_ByteCount32_T DataTransferSize; /* Bytes 4-7 */ - DAC960_BusAddress64_T RequestSenseBusAddress; /* Bytes 8-15 */ - DAC960_V2_PhysicalDevice_T PhysicalDevice; /* Bytes 16-18 */ - DAC960_V2_CommandTimeout_T CommandTimeout; /* Byte 19 */ - unsigned char RequestSenseSize; /* Byte 20 */ - unsigned char CDBLength; /* Byte 21 */ - unsigned char SCSI_CDB[10]; /* Bytes 22-31 */ - DAC960_V2_DataTransferMemoryAddress_T - DataTransferMemoryAddress; /* Bytes 32-63 */ - } SCSI_10; - struct { - DAC960_V2_CommandIdentifier_T CommandIdentifier; /* Bytes 0-1 */ - DAC960_V2_CommandOpcode_T CommandOpcode; /* Byte 2 */ - DAC960_V2_CommandControlBits_T CommandControlBits; /* Byte 3 */ - DAC960_ByteCount32_T DataTransferSize; /* Bytes 4-7 */ - DAC960_BusAddress64_T RequestSenseBusAddress; /* Bytes 8-15 */ - DAC960_V2_PhysicalDevice_T PhysicalDevice; /* Bytes 16-18 */ - DAC960_V2_CommandTimeout_T CommandTimeout; /* Byte 19 */ - unsigned char RequestSenseSize; /* Byte 20 */ - unsigned char CDBLength; /* Byte 21 */ - unsigned short :16; /* Bytes 22-23 */ - DAC960_BusAddress64_T SCSI_CDB_BusAddress; /* Bytes 24-31 */ - DAC960_V2_DataTransferMemoryAddress_T - DataTransferMemoryAddress; /* Bytes 32-63 */ - } SCSI_255; - struct { - DAC960_V2_CommandIdentifier_T CommandIdentifier; /* Bytes 0-1 */ - DAC960_V2_CommandOpcode_T CommandOpcode; /* Byte 2 */ - DAC960_V2_CommandControlBits_T CommandControlBits; /* Byte 3 */ - DAC960_ByteCount32_T DataTransferSize:24; /* Bytes 4-6 */ - unsigned char DataTransferPageNumber; /* Byte 7 */ - DAC960_BusAddress64_T RequestSenseBusAddress; /* Bytes 8-15 */ - unsigned short :16; /* Bytes 16-17 */ - unsigned char ControllerNumber; /* Byte 18 */ - DAC960_V2_CommandTimeout_T CommandTimeout; /* Byte 19 */ - unsigned char RequestSenseSize; /* Byte 20 */ - unsigned char IOCTL_Opcode; /* Byte 21 */ - unsigned char Reserved[10]; /* Bytes 22-31 */ - DAC960_V2_DataTransferMemoryAddress_T - DataTransferMemoryAddress; /* Bytes 32-63 */ - } ControllerInfo; - struct { - DAC960_V2_CommandIdentifier_T CommandIdentifier; /* Bytes 0-1 */ - DAC960_V2_CommandOpcode_T CommandOpcode; /* Byte 2 */ - DAC960_V2_CommandControlBits_T CommandControlBits; /* Byte 3 */ - DAC960_ByteCount32_T DataTransferSize:24; /* Bytes 4-6 */ - unsigned char DataTransferPageNumber; /* Byte 7 */ - DAC960_BusAddress64_T RequestSenseBusAddress; /* Bytes 8-15 */ - DAC960_V2_LogicalDevice_T LogicalDevice; /* Bytes 16-18 */ - DAC960_V2_CommandTimeout_T CommandTimeout; /* Byte 19 */ - unsigned char RequestSenseSize; /* Byte 20 */ - unsigned char IOCTL_Opcode; /* Byte 21 */ - unsigned char Reserved[10]; /* Bytes 22-31 */ - DAC960_V2_DataTransferMemoryAddress_T - DataTransferMemoryAddress; /* Bytes 32-63 */ - } LogicalDeviceInfo; - struct { - DAC960_V2_CommandIdentifier_T CommandIdentifier; /* Bytes 0-1 */ - DAC960_V2_CommandOpcode_T CommandOpcode; /* Byte 2 */ - DAC960_V2_CommandControlBits_T CommandControlBits; /* Byte 3 */ - DAC960_ByteCount32_T DataTransferSize:24; /* Bytes 4-6 */ - unsigned char DataTransferPageNumber; /* Byte 7 */ - DAC960_BusAddress64_T RequestSenseBusAddress; /* Bytes 8-15 */ - DAC960_V2_PhysicalDevice_T PhysicalDevice; /* Bytes 16-18 */ - DAC960_V2_CommandTimeout_T CommandTimeout; /* Byte 19 */ - unsigned char RequestSenseSize; /* Byte 20 */ - unsigned char IOCTL_Opcode; /* Byte 21 */ - unsigned char Reserved[10]; /* Bytes 22-31 */ - DAC960_V2_DataTransferMemoryAddress_T - DataTransferMemoryAddress; /* Bytes 32-63 */ - } PhysicalDeviceInfo; - struct { - DAC960_V2_CommandIdentifier_T CommandIdentifier; /* Bytes 0-1 */ - DAC960_V2_CommandOpcode_T CommandOpcode; /* Byte 2 */ - DAC960_V2_CommandControlBits_T CommandControlBits; /* Byte 3 */ - DAC960_ByteCount32_T DataTransferSize:24; /* Bytes 4-6 */ - unsigned char DataTransferPageNumber; /* Byte 7 */ - DAC960_BusAddress64_T RequestSenseBusAddress; /* Bytes 8-15 */ - unsigned short EventSequenceNumberHigh16; /* Bytes 16-17 */ - unsigned char ControllerNumber; /* Byte 18 */ - DAC960_V2_CommandTimeout_T CommandTimeout; /* Byte 19 */ - unsigned char RequestSenseSize; /* Byte 20 */ - unsigned char IOCTL_Opcode; /* Byte 21 */ - unsigned short EventSequenceNumberLow16; /* Bytes 22-23 */ - unsigned char Reserved[8]; /* Bytes 24-31 */ - DAC960_V2_DataTransferMemoryAddress_T - DataTransferMemoryAddress; /* Bytes 32-63 */ - } GetEvent; - struct { - DAC960_V2_CommandIdentifier_T CommandIdentifier; /* Bytes 0-1 */ - DAC960_V2_CommandOpcode_T CommandOpcode; /* Byte 2 */ - DAC960_V2_CommandControlBits_T CommandControlBits; /* Byte 3 */ - DAC960_ByteCount32_T DataTransferSize:24; /* Bytes 4-6 */ - unsigned char DataTransferPageNumber; /* Byte 7 */ - DAC960_BusAddress64_T RequestSenseBusAddress; /* Bytes 8-15 */ - DAC960_V2_LogicalDevice_T LogicalDevice; /* Bytes 16-18 */ - DAC960_V2_CommandTimeout_T CommandTimeout; /* Byte 19 */ - unsigned char RequestSenseSize; /* Byte 20 */ - unsigned char IOCTL_Opcode; /* Byte 21 */ - union { - DAC960_V2_LogicalDeviceState_T LogicalDeviceState; - DAC960_V2_PhysicalDeviceState_T PhysicalDeviceState; - } DeviceState; /* Byte 22 */ - unsigned char Reserved[9]; /* Bytes 23-31 */ - DAC960_V2_DataTransferMemoryAddress_T - DataTransferMemoryAddress; /* Bytes 32-63 */ - } SetDeviceState; - struct { - DAC960_V2_CommandIdentifier_T CommandIdentifier; /* Bytes 0-1 */ - DAC960_V2_CommandOpcode_T CommandOpcode; /* Byte 2 */ - DAC960_V2_CommandControlBits_T CommandControlBits; /* Byte 3 */ - DAC960_ByteCount32_T DataTransferSize:24; /* Bytes 4-6 */ - unsigned char DataTransferPageNumber; /* Byte 7 */ - DAC960_BusAddress64_T RequestSenseBusAddress; /* Bytes 8-15 */ - DAC960_V2_LogicalDevice_T LogicalDevice; /* Bytes 16-18 */ - DAC960_V2_CommandTimeout_T CommandTimeout; /* Byte 19 */ - unsigned char RequestSenseSize; /* Byte 20 */ - unsigned char IOCTL_Opcode; /* Byte 21 */ - bool RestoreConsistency:1; /* Byte 22 Bit 0 */ - bool InitializedAreaOnly:1; /* Byte 22 Bit 1 */ - unsigned char :6; /* Byte 22 Bits 2-7 */ - unsigned char Reserved[9]; /* Bytes 23-31 */ - DAC960_V2_DataTransferMemoryAddress_T - DataTransferMemoryAddress; /* Bytes 32-63 */ - } ConsistencyCheck; - struct { - DAC960_V2_CommandIdentifier_T CommandIdentifier; /* Bytes 0-1 */ - DAC960_V2_CommandOpcode_T CommandOpcode; /* Byte 2 */ - DAC960_V2_CommandControlBits_T CommandControlBits; /* Byte 3 */ - unsigned char FirstCommandMailboxSizeKB; /* Byte 4 */ - unsigned char FirstStatusMailboxSizeKB; /* Byte 5 */ - unsigned char SecondCommandMailboxSizeKB; /* Byte 6 */ - unsigned char SecondStatusMailboxSizeKB; /* Byte 7 */ - DAC960_BusAddress64_T RequestSenseBusAddress; /* Bytes 8-15 */ - unsigned int :24; /* Bytes 16-18 */ - DAC960_V2_CommandTimeout_T CommandTimeout; /* Byte 19 */ - unsigned char RequestSenseSize; /* Byte 20 */ - unsigned char IOCTL_Opcode; /* Byte 21 */ - unsigned char HealthStatusBufferSizeKB; /* Byte 22 */ - unsigned char :8; /* Byte 23 */ - DAC960_BusAddress64_T HealthStatusBufferBusAddress; /* Bytes 24-31 */ - DAC960_BusAddress64_T FirstCommandMailboxBusAddress; /* Bytes 32-39 */ - DAC960_BusAddress64_T FirstStatusMailboxBusAddress; /* Bytes 40-47 */ - DAC960_BusAddress64_T SecondCommandMailboxBusAddress; /* Bytes 48-55 */ - DAC960_BusAddress64_T SecondStatusMailboxBusAddress; /* Bytes 56-63 */ - } SetMemoryMailbox; - struct { - DAC960_V2_CommandIdentifier_T CommandIdentifier; /* Bytes 0-1 */ - DAC960_V2_CommandOpcode_T CommandOpcode; /* Byte 2 */ - DAC960_V2_CommandControlBits_T CommandControlBits; /* Byte 3 */ - DAC960_ByteCount32_T DataTransferSize:24; /* Bytes 4-6 */ - unsigned char DataTransferPageNumber; /* Byte 7 */ - DAC960_BusAddress64_T RequestSenseBusAddress; /* Bytes 8-15 */ - DAC960_V2_PhysicalDevice_T PhysicalDevice; /* Bytes 16-18 */ - DAC960_V2_CommandTimeout_T CommandTimeout; /* Byte 19 */ - unsigned char RequestSenseSize; /* Byte 20 */ - unsigned char IOCTL_Opcode; /* Byte 21 */ - DAC960_V2_OperationDevice_T OperationDevice; /* Byte 22 */ - unsigned char Reserved[9]; /* Bytes 23-31 */ - DAC960_V2_DataTransferMemoryAddress_T - DataTransferMemoryAddress; /* Bytes 32-63 */ - } DeviceOperation; -} -DAC960_V2_CommandMailbox_T; - - -/* - Define the DAC960 Driver IOCTL requests. -*/ - -#define DAC960_IOCTL_GET_CONTROLLER_COUNT 0xDAC001 -#define DAC960_IOCTL_GET_CONTROLLER_INFO 0xDAC002 -#define DAC960_IOCTL_V1_EXECUTE_COMMAND 0xDAC003 -#define DAC960_IOCTL_V2_EXECUTE_COMMAND 0xDAC004 -#define DAC960_IOCTL_V2_GET_HEALTH_STATUS 0xDAC005 - - -/* - Define the DAC960_IOCTL_GET_CONTROLLER_INFO reply structure. -*/ - -typedef struct DAC960_ControllerInfo -{ - unsigned char ControllerNumber; - unsigned char FirmwareType; - unsigned char Channels; - unsigned char Targets; - unsigned char PCI_Bus; - unsigned char PCI_Device; - unsigned char PCI_Function; - unsigned char IRQ_Channel; - DAC960_PCI_Address_T PCI_Address; - unsigned char ModelName[20]; - unsigned char FirmwareVersion[12]; -} -DAC960_ControllerInfo_T; - - -/* - Define the User Mode DAC960_IOCTL_V1_EXECUTE_COMMAND request structure. -*/ - -typedef struct DAC960_V1_UserCommand -{ - unsigned char ControllerNumber; - DAC960_V1_CommandMailbox_T CommandMailbox; - int DataTransferLength; - void __user *DataTransferBuffer; - DAC960_V1_DCDB_T __user *DCDB; -} -DAC960_V1_UserCommand_T; - - -/* - Define the Kernel Mode DAC960_IOCTL_V1_EXECUTE_COMMAND request structure. -*/ - -typedef struct DAC960_V1_KernelCommand -{ - unsigned char ControllerNumber; - DAC960_V1_CommandMailbox_T CommandMailbox; - int DataTransferLength; - void *DataTransferBuffer; - DAC960_V1_DCDB_T *DCDB; - DAC960_V1_CommandStatus_T CommandStatus; - void (*CompletionFunction)(struct DAC960_V1_KernelCommand *); - void *CompletionData; -} -DAC960_V1_KernelCommand_T; - - -/* - Define the User Mode DAC960_IOCTL_V2_EXECUTE_COMMAND request structure. -*/ - -typedef struct DAC960_V2_UserCommand -{ - unsigned char ControllerNumber; - DAC960_V2_CommandMailbox_T CommandMailbox; - int DataTransferLength; - int RequestSenseLength; - void __user *DataTransferBuffer; - void __user *RequestSenseBuffer; -} -DAC960_V2_UserCommand_T; - - -/* - Define the Kernel Mode DAC960_IOCTL_V2_EXECUTE_COMMAND request structure. -*/ - -typedef struct DAC960_V2_KernelCommand -{ - unsigned char ControllerNumber; - DAC960_V2_CommandMailbox_T CommandMailbox; - int DataTransferLength; - int RequestSenseLength; - void *DataTransferBuffer; - void *RequestSenseBuffer; - DAC960_V2_CommandStatus_T CommandStatus; - void (*CompletionFunction)(struct DAC960_V2_KernelCommand *); - void *CompletionData; -} -DAC960_V2_KernelCommand_T; - - -/* - Define the User Mode DAC960_IOCTL_V2_GET_HEALTH_STATUS request structure. -*/ - -typedef struct DAC960_V2_GetHealthStatus -{ - unsigned char ControllerNumber; - DAC960_V2_HealthStatusBuffer_T __user *HealthStatusBuffer; -} -DAC960_V2_GetHealthStatus_T; - - -/* - Import the Kernel Mode IOCTL interface. -*/ - -extern int DAC960_KernelIOCTL(unsigned int Request, void *Argument); - - -/* - DAC960_DriverVersion protects the private portion of this file. -*/ - -#ifdef DAC960_DriverVersion - - -/* - Define the maximum Driver Queue Depth and Controller Queue Depth supported - by DAC960 V1 and V2 Firmware Controllers. -*/ - -#define DAC960_MaxDriverQueueDepth 511 -#define DAC960_MaxControllerQueueDepth 512 - - -/* - Define the maximum number of Scatter/Gather Segments supported for any - DAC960 V1 and V2 Firmware controller. -*/ - -#define DAC960_V1_ScatterGatherLimit 33 -#define DAC960_V2_ScatterGatherLimit 128 - - -/* - Define the number of Command Mailboxes and Status Mailboxes used by the - DAC960 V1 and V2 Firmware Memory Mailbox Interface. -*/ - -#define DAC960_V1_CommandMailboxCount 256 -#define DAC960_V1_StatusMailboxCount 1024 -#define DAC960_V2_CommandMailboxCount 512 -#define DAC960_V2_StatusMailboxCount 512 - - -/* - Define the DAC960 Controller Monitoring Timer Interval. -*/ - -#define DAC960_MonitoringTimerInterval (10 * HZ) - - -/* - Define the DAC960 Controller Secondary Monitoring Interval. -*/ - -#define DAC960_SecondaryMonitoringInterval (60 * HZ) - - -/* - Define the DAC960 Controller Health Status Monitoring Interval. -*/ - -#define DAC960_HealthStatusMonitoringInterval (1 * HZ) - - -/* - Define the DAC960 Controller Progress Reporting Interval. -*/ - -#define DAC960_ProgressReportingInterval (60 * HZ) - - -/* - Define the maximum number of Partitions allowed for each Logical Drive. -*/ - -#define DAC960_MaxPartitions 8 -#define DAC960_MaxPartitionsBits 3 - -/* - Define the DAC960 Controller fixed Block Size and Block Size Bits. -*/ - -#define DAC960_BlockSize 512 -#define DAC960_BlockSizeBits 9 - - -/* - Define the number of Command structures that should be allocated as a - group to optimize kernel memory allocation. -*/ - -#define DAC960_V1_CommandAllocationGroupSize 11 -#define DAC960_V2_CommandAllocationGroupSize 29 - - -/* - Define the Controller Line Buffer, Progress Buffer, User Message, and - Initial Status Buffer sizes. -*/ - -#define DAC960_LineBufferSize 100 -#define DAC960_ProgressBufferSize 200 -#define DAC960_UserMessageSize 200 -#define DAC960_InitialStatusBufferSize (8192-32) - - -/* - Define the DAC960 Controller Firmware Types. -*/ - -typedef enum -{ - DAC960_V1_Controller = 1, - DAC960_V2_Controller = 2 -} -DAC960_FirmwareType_T; - - -/* - Define the DAC960 Controller Hardware Types. -*/ - -typedef enum -{ - DAC960_BA_Controller = 1, /* eXtremeRAID 2000 */ - DAC960_LP_Controller = 2, /* AcceleRAID 352 */ - DAC960_LA_Controller = 3, /* DAC1164P */ - DAC960_PG_Controller = 4, /* DAC960PTL/PJ/PG */ - DAC960_PD_Controller = 5, /* DAC960PU/PD/PL/P */ - DAC960_P_Controller = 6, /* DAC960PU/PD/PL/P */ - DAC960_GEM_Controller = 7, /* AcceleRAID 4/5/600 */ -} -DAC960_HardwareType_T; - - -/* - Define the Driver Message Levels. -*/ - -typedef enum DAC960_MessageLevel -{ - DAC960_AnnounceLevel = 0, - DAC960_InfoLevel = 1, - DAC960_NoticeLevel = 2, - DAC960_WarningLevel = 3, - DAC960_ErrorLevel = 4, - DAC960_ProgressLevel = 5, - DAC960_CriticalLevel = 6, - DAC960_UserCriticalLevel = 7 -} -DAC960_MessageLevel_T; - -static char - *DAC960_MessageLevelMap[] = - { KERN_NOTICE, KERN_NOTICE, KERN_NOTICE, KERN_WARNING, - KERN_ERR, KERN_CRIT, KERN_CRIT, KERN_CRIT }; - - -/* - Define Driver Message macros. -*/ - -#define DAC960_Announce(Format, Arguments...) \ - DAC960_Message(DAC960_AnnounceLevel, Format, ##Arguments) - -#define DAC960_Info(Format, Arguments...) \ - DAC960_Message(DAC960_InfoLevel, Format, ##Arguments) - -#define DAC960_Notice(Format, Arguments...) \ - DAC960_Message(DAC960_NoticeLevel, Format, ##Arguments) - -#define DAC960_Warning(Format, Arguments...) \ - DAC960_Message(DAC960_WarningLevel, Format, ##Arguments) - -#define DAC960_Error(Format, Arguments...) \ - DAC960_Message(DAC960_ErrorLevel, Format, ##Arguments) - -#define DAC960_Progress(Format, Arguments...) \ - DAC960_Message(DAC960_ProgressLevel, Format, ##Arguments) - -#define DAC960_Critical(Format, Arguments...) \ - DAC960_Message(DAC960_CriticalLevel, Format, ##Arguments) - -#define DAC960_UserCritical(Format, Arguments...) \ - DAC960_Message(DAC960_UserCriticalLevel, Format, ##Arguments) - - -struct DAC960_privdata { - DAC960_HardwareType_T HardwareType; - DAC960_FirmwareType_T FirmwareType; - irq_handler_t InterruptHandler; - unsigned int MemoryWindowSize; -}; - - -/* - Define the DAC960 V1 Firmware Controller Status Mailbox structure. -*/ - -typedef union DAC960_V1_StatusMailbox -{ - unsigned int Word; /* Word 0 */ - struct { - DAC960_V1_CommandIdentifier_T CommandIdentifier; /* Byte 0 */ - unsigned char :7; /* Byte 1 Bits 0-6 */ - bool Valid:1; /* Byte 1 Bit 7 */ - DAC960_V1_CommandStatus_T CommandStatus; /* Bytes 2-3 */ - } Fields; -} -DAC960_V1_StatusMailbox_T; - - -/* - Define the DAC960 V2 Firmware Controller Status Mailbox structure. -*/ - -typedef union DAC960_V2_StatusMailbox -{ - unsigned int Words[2]; /* Words 0-1 */ - struct { - DAC960_V2_CommandIdentifier_T CommandIdentifier; /* Bytes 0-1 */ - DAC960_V2_CommandStatus_T CommandStatus; /* Byte 2 */ - unsigned char RequestSenseLength; /* Byte 3 */ - int DataTransferResidue; /* Bytes 4-7 */ - } Fields; -} -DAC960_V2_StatusMailbox_T; - - -/* - Define the DAC960 Driver Command Types. -*/ - -typedef enum -{ - DAC960_ReadCommand = 1, - DAC960_WriteCommand = 2, - DAC960_ReadRetryCommand = 3, - DAC960_WriteRetryCommand = 4, - DAC960_MonitoringCommand = 5, - DAC960_ImmediateCommand = 6, - DAC960_QueuedCommand = 7 -} -DAC960_CommandType_T; - - -/* - Define the DAC960 Driver Command structure. -*/ - -typedef struct DAC960_Command -{ - int CommandIdentifier; - DAC960_CommandType_T CommandType; - struct DAC960_Controller *Controller; - struct DAC960_Command *Next; - struct completion *Completion; - unsigned int LogicalDriveNumber; - unsigned int BlockNumber; - unsigned int BlockCount; - unsigned int SegmentCount; - int DmaDirection; - struct scatterlist *cmd_sglist; - struct request *Request; - union { - struct { - DAC960_V1_CommandMailbox_T CommandMailbox; - DAC960_V1_KernelCommand_T *KernelCommand; - DAC960_V1_CommandStatus_T CommandStatus; - DAC960_V1_ScatterGatherSegment_T *ScatterGatherList; - dma_addr_t ScatterGatherListDMA; - struct scatterlist ScatterList[DAC960_V1_ScatterGatherLimit]; - unsigned int EndMarker[0]; - } V1; - struct { - DAC960_V2_CommandMailbox_T CommandMailbox; - DAC960_V2_KernelCommand_T *KernelCommand; - DAC960_V2_CommandStatus_T CommandStatus; - unsigned char RequestSenseLength; - int DataTransferResidue; - DAC960_V2_ScatterGatherSegment_T *ScatterGatherList; - dma_addr_t ScatterGatherListDMA; - DAC960_SCSI_RequestSense_T *RequestSense; - dma_addr_t RequestSenseDMA; - struct scatterlist ScatterList[DAC960_V2_ScatterGatherLimit]; - unsigned int EndMarker[0]; - } V2; - } FW; -} -DAC960_Command_T; - - -/* - Define the DAC960 Driver Controller structure. -*/ - -typedef struct DAC960_Controller -{ - void __iomem *BaseAddress; - void __iomem *MemoryMappedAddress; - DAC960_FirmwareType_T FirmwareType; - DAC960_HardwareType_T HardwareType; - DAC960_IO_Address_T IO_Address; - DAC960_PCI_Address_T PCI_Address; - struct pci_dev *PCIDevice; - unsigned char ControllerNumber; - unsigned char ControllerName[4]; - unsigned char ModelName[20]; - unsigned char FullModelName[28]; - unsigned char FirmwareVersion[12]; - unsigned char Bus; - unsigned char Device; - unsigned char Function; - unsigned char IRQ_Channel; - unsigned char Channels; - unsigned char Targets; - unsigned char MemorySize; - unsigned char LogicalDriveCount; - unsigned short CommandAllocationGroupSize; - unsigned short ControllerQueueDepth; - unsigned short DriverQueueDepth; - unsigned short MaxBlocksPerCommand; - unsigned short ControllerScatterGatherLimit; - unsigned short DriverScatterGatherLimit; - unsigned int CombinedStatusBufferLength; - unsigned int InitialStatusLength; - unsigned int CurrentStatusLength; - unsigned int ProgressBufferLength; - unsigned int UserStatusLength; - struct dma_loaf DmaPages; - unsigned long MonitoringTimerCount; - unsigned long PrimaryMonitoringTime; - unsigned long SecondaryMonitoringTime; - unsigned long ShutdownMonitoringTimer; - unsigned long LastProgressReportTime; - unsigned long LastCurrentStatusTime; - bool ControllerInitialized; - bool MonitoringCommandDeferred; - bool EphemeralProgressMessage; - bool DriveSpinUpMessageDisplayed; - bool MonitoringAlertMode; - bool SuppressEnclosureMessages; - struct timer_list MonitoringTimer; - struct gendisk *disks[DAC960_MaxLogicalDrives]; - struct dma_pool *ScatterGatherPool; - DAC960_Command_T *FreeCommands; - unsigned char *CombinedStatusBuffer; - unsigned char *CurrentStatusBuffer; - struct request_queue *RequestQueue[DAC960_MaxLogicalDrives]; - int req_q_index; - spinlock_t queue_lock; - wait_queue_head_t CommandWaitQueue; - wait_queue_head_t HealthStatusWaitQueue; - DAC960_Command_T InitialCommand; - DAC960_Command_T *Commands[DAC960_MaxDriverQueueDepth]; - struct proc_dir_entry *ControllerProcEntry; - bool LogicalDriveInitiallyAccessible[DAC960_MaxLogicalDrives]; - void (*QueueCommand)(DAC960_Command_T *Command); - bool (*ReadControllerConfiguration)(struct DAC960_Controller *); - bool (*ReadDeviceConfiguration)(struct DAC960_Controller *); - bool (*ReportDeviceConfiguration)(struct DAC960_Controller *); - void (*QueueReadWriteCommand)(DAC960_Command_T *Command); - union { - struct { - unsigned char GeometryTranslationHeads; - unsigned char GeometryTranslationSectors; - unsigned char PendingRebuildFlag; - unsigned short StripeSize; - unsigned short SegmentSize; - unsigned short NewEventLogSequenceNumber; - unsigned short OldEventLogSequenceNumber; - unsigned short DeviceStateChannel; - unsigned short DeviceStateTargetID; - bool DualModeMemoryMailboxInterface; - bool BackgroundInitializationStatusSupported; - bool SAFTE_EnclosureManagementEnabled; - bool NeedLogicalDriveInformation; - bool NeedErrorTableInformation; - bool NeedDeviceStateInformation; - bool NeedDeviceInquiryInformation; - bool NeedDeviceSerialNumberInformation; - bool NeedRebuildProgress; - bool NeedConsistencyCheckProgress; - bool NeedBackgroundInitializationStatus; - bool StartDeviceStateScan; - bool RebuildProgressFirst; - bool RebuildFlagPending; - bool RebuildStatusPending; - - dma_addr_t FirstCommandMailboxDMA; - DAC960_V1_CommandMailbox_T *FirstCommandMailbox; - DAC960_V1_CommandMailbox_T *LastCommandMailbox; - DAC960_V1_CommandMailbox_T *NextCommandMailbox; - DAC960_V1_CommandMailbox_T *PreviousCommandMailbox1; - DAC960_V1_CommandMailbox_T *PreviousCommandMailbox2; - - dma_addr_t FirstStatusMailboxDMA; - DAC960_V1_StatusMailbox_T *FirstStatusMailbox; - DAC960_V1_StatusMailbox_T *LastStatusMailbox; - DAC960_V1_StatusMailbox_T *NextStatusMailbox; - - DAC960_V1_DCDB_T *MonitoringDCDB; - dma_addr_t MonitoringDCDB_DMA; - - DAC960_V1_Enquiry_T Enquiry; - DAC960_V1_Enquiry_T *NewEnquiry; - dma_addr_t NewEnquiryDMA; - - DAC960_V1_ErrorTable_T ErrorTable; - DAC960_V1_ErrorTable_T *NewErrorTable; - dma_addr_t NewErrorTableDMA; - - DAC960_V1_EventLogEntry_T *EventLogEntry; - dma_addr_t EventLogEntryDMA; - - DAC960_V1_RebuildProgress_T *RebuildProgress; - dma_addr_t RebuildProgressDMA; - DAC960_V1_CommandStatus_T LastRebuildStatus; - DAC960_V1_CommandStatus_T PendingRebuildStatus; - - DAC960_V1_LogicalDriveInformationArray_T LogicalDriveInformation; - DAC960_V1_LogicalDriveInformationArray_T *NewLogicalDriveInformation; - dma_addr_t NewLogicalDriveInformationDMA; - - DAC960_V1_BackgroundInitializationStatus_T - *BackgroundInitializationStatus; - dma_addr_t BackgroundInitializationStatusDMA; - DAC960_V1_BackgroundInitializationStatus_T - LastBackgroundInitializationStatus; - - DAC960_V1_DeviceState_T - DeviceState[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets]; - DAC960_V1_DeviceState_T *NewDeviceState; - dma_addr_t NewDeviceStateDMA; - - DAC960_SCSI_Inquiry_T - InquiryStandardData[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets]; - DAC960_SCSI_Inquiry_T *NewInquiryStandardData; - dma_addr_t NewInquiryStandardDataDMA; - - DAC960_SCSI_Inquiry_UnitSerialNumber_T - InquiryUnitSerialNumber[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets]; - DAC960_SCSI_Inquiry_UnitSerialNumber_T *NewInquiryUnitSerialNumber; - dma_addr_t NewInquiryUnitSerialNumberDMA; - - int DeviceResetCount[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets]; - bool DirectCommandActive[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets]; - } V1; - struct { - unsigned int StatusChangeCounter; - unsigned int NextEventSequenceNumber; - unsigned int PhysicalDeviceIndex; - bool NeedLogicalDeviceInformation; - bool NeedPhysicalDeviceInformation; - bool NeedDeviceSerialNumberInformation; - bool StartLogicalDeviceInformationScan; - bool StartPhysicalDeviceInformationScan; - struct dma_pool *RequestSensePool; - - dma_addr_t FirstCommandMailboxDMA; - DAC960_V2_CommandMailbox_T *FirstCommandMailbox; - DAC960_V2_CommandMailbox_T *LastCommandMailbox; - DAC960_V2_CommandMailbox_T *NextCommandMailbox; - DAC960_V2_CommandMailbox_T *PreviousCommandMailbox1; - DAC960_V2_CommandMailbox_T *PreviousCommandMailbox2; - - dma_addr_t FirstStatusMailboxDMA; - DAC960_V2_StatusMailbox_T *FirstStatusMailbox; - DAC960_V2_StatusMailbox_T *LastStatusMailbox; - DAC960_V2_StatusMailbox_T *NextStatusMailbox; - - dma_addr_t HealthStatusBufferDMA; - DAC960_V2_HealthStatusBuffer_T *HealthStatusBuffer; - - DAC960_V2_ControllerInfo_T ControllerInformation; - DAC960_V2_ControllerInfo_T *NewControllerInformation; - dma_addr_t NewControllerInformationDMA; - - DAC960_V2_LogicalDeviceInfo_T - *LogicalDeviceInformation[DAC960_MaxLogicalDrives]; - DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInformation; - dma_addr_t NewLogicalDeviceInformationDMA; - - DAC960_V2_PhysicalDeviceInfo_T - *PhysicalDeviceInformation[DAC960_V2_MaxPhysicalDevices]; - DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInformation; - dma_addr_t NewPhysicalDeviceInformationDMA; - - DAC960_SCSI_Inquiry_UnitSerialNumber_T *NewInquiryUnitSerialNumber; - dma_addr_t NewInquiryUnitSerialNumberDMA; - DAC960_SCSI_Inquiry_UnitSerialNumber_T - *InquiryUnitSerialNumber[DAC960_V2_MaxPhysicalDevices]; - - DAC960_V2_Event_T *Event; - dma_addr_t EventDMA; - - DAC960_V2_PhysicalToLogicalDevice_T *PhysicalToLogicalDevice; - dma_addr_t PhysicalToLogicalDeviceDMA; - - DAC960_V2_PhysicalDevice_T - LogicalDriveToVirtualDevice[DAC960_MaxLogicalDrives]; - bool LogicalDriveFoundDuringScan[DAC960_MaxLogicalDrives]; - } V2; - } FW; - unsigned char ProgressBuffer[DAC960_ProgressBufferSize]; - unsigned char UserStatusBuffer[DAC960_UserMessageSize]; -} -DAC960_Controller_T; - - -/* - Simplify access to Firmware Version Dependent Data Structure Components - and Functions. -*/ - -#define V1 FW.V1 -#define V2 FW.V2 -#define DAC960_QueueCommand(Command) \ - (Controller->QueueCommand)(Command) -#define DAC960_ReadControllerConfiguration(Controller) \ - (Controller->ReadControllerConfiguration)(Controller) -#define DAC960_ReadDeviceConfiguration(Controller) \ - (Controller->ReadDeviceConfiguration)(Controller) -#define DAC960_ReportDeviceConfiguration(Controller) \ - (Controller->ReportDeviceConfiguration)(Controller) -#define DAC960_QueueReadWriteCommand(Command) \ - (Controller->QueueReadWriteCommand)(Command) - -/* - * dma_addr_writeql is provided to write dma_addr_t types - * to a 64-bit pci address space register. The controller - * will accept having the register written as two 32-bit - * values. - * - * In HIGHMEM kernels, dma_addr_t is a 64-bit value. - * without HIGHMEM, dma_addr_t is a 32-bit value. - * - * The compiler should always fix up the assignment - * to u.wq appropriately, depending upon the size of - * dma_addr_t. - */ -static inline -void dma_addr_writeql(dma_addr_t addr, void __iomem *write_address) -{ - union { - u64 wq; - uint wl[2]; - } u; - - u.wq = addr; - - writel(u.wl[0], write_address); - writel(u.wl[1], write_address + 4); -} - -/* - Define the DAC960 GEM Series Controller Interface Register Offsets. - */ - -#define DAC960_GEM_RegisterWindowSize 0x600 - -typedef enum -{ - DAC960_GEM_InboundDoorBellRegisterReadSetOffset = 0x214, - DAC960_GEM_InboundDoorBellRegisterClearOffset = 0x218, - DAC960_GEM_OutboundDoorBellRegisterReadSetOffset = 0x224, - DAC960_GEM_OutboundDoorBellRegisterClearOffset = 0x228, - DAC960_GEM_InterruptStatusRegisterOffset = 0x208, - DAC960_GEM_InterruptMaskRegisterReadSetOffset = 0x22C, - DAC960_GEM_InterruptMaskRegisterClearOffset = 0x230, - DAC960_GEM_CommandMailboxBusAddressOffset = 0x510, - DAC960_GEM_CommandStatusOffset = 0x518, - DAC960_GEM_ErrorStatusRegisterReadSetOffset = 0x224, - DAC960_GEM_ErrorStatusRegisterClearOffset = 0x228, -} -DAC960_GEM_RegisterOffsets_T; - -/* - Define the structure of the DAC960 GEM Series Inbound Door Bell - */ - -typedef union DAC960_GEM_InboundDoorBellRegister -{ - unsigned int All; - struct { - unsigned int :24; - bool HardwareMailboxNewCommand:1; - bool AcknowledgeHardwareMailboxStatus:1; - bool GenerateInterrupt:1; - bool ControllerReset:1; - bool MemoryMailboxNewCommand:1; - unsigned int :3; - } Write; - struct { - unsigned int :24; - bool HardwareMailboxFull:1; - bool InitializationInProgress:1; - unsigned int :6; - } Read; -} -DAC960_GEM_InboundDoorBellRegister_T; - -/* - Define the structure of the DAC960 GEM Series Outbound Door Bell Register. - */ -typedef union DAC960_GEM_OutboundDoorBellRegister -{ - unsigned int All; - struct { - unsigned int :24; - bool AcknowledgeHardwareMailboxInterrupt:1; - bool AcknowledgeMemoryMailboxInterrupt:1; - unsigned int :6; - } Write; - struct { - unsigned int :24; - bool HardwareMailboxStatusAvailable:1; - bool MemoryMailboxStatusAvailable:1; - unsigned int :6; - } Read; -} -DAC960_GEM_OutboundDoorBellRegister_T; - -/* - Define the structure of the DAC960 GEM Series Interrupt Mask Register. - */ -typedef union DAC960_GEM_InterruptMaskRegister -{ - unsigned int All; - struct { - unsigned int :16; - unsigned int :8; - unsigned int HardwareMailboxInterrupt:1; - unsigned int MemoryMailboxInterrupt:1; - unsigned int :6; - } Bits; -} -DAC960_GEM_InterruptMaskRegister_T; - -/* - Define the structure of the DAC960 GEM Series Error Status Register. - */ - -typedef union DAC960_GEM_ErrorStatusRegister -{ - unsigned int All; - struct { - unsigned int :24; - unsigned int :5; - bool ErrorStatusPending:1; - unsigned int :2; - } Bits; -} -DAC960_GEM_ErrorStatusRegister_T; - -/* - Define inline functions to provide an abstraction for reading and writing the - DAC960 GEM Series Controller Interface Registers. -*/ - -static inline -void DAC960_GEM_HardwareMailboxNewCommand(void __iomem *ControllerBaseAddress) -{ - DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true; - writel(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterReadSetOffset); -} - -static inline -void DAC960_GEM_AcknowledgeHardwareMailboxStatus(void __iomem *ControllerBaseAddress) -{ - DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true; - writel(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterClearOffset); -} - -static inline -void DAC960_GEM_GenerateInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.GenerateInterrupt = true; - writel(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterReadSetOffset); -} - -static inline -void DAC960_GEM_ControllerReset(void __iomem *ControllerBaseAddress) -{ - DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.ControllerReset = true; - writel(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterReadSetOffset); -} - -static inline -void DAC960_GEM_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress) -{ - DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true; - writel(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterReadSetOffset); -} - -static inline -bool DAC960_GEM_HardwareMailboxFullP(void __iomem *ControllerBaseAddress) -{ - DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = - readl(ControllerBaseAddress + - DAC960_GEM_InboundDoorBellRegisterReadSetOffset); - return InboundDoorBellRegister.Read.HardwareMailboxFull; -} - -static inline -bool DAC960_GEM_InitializationInProgressP(void __iomem *ControllerBaseAddress) -{ - DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = - readl(ControllerBaseAddress + - DAC960_GEM_InboundDoorBellRegisterReadSetOffset); - return InboundDoorBellRegister.Read.InitializationInProgress; -} - -static inline -void DAC960_GEM_AcknowledgeHardwareMailboxInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = 0; - OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true; - writel(OutboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_GEM_OutboundDoorBellRegisterClearOffset); -} - -static inline -void DAC960_GEM_AcknowledgeMemoryMailboxInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = 0; - OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true; - writel(OutboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_GEM_OutboundDoorBellRegisterClearOffset); -} - -static inline -void DAC960_GEM_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = 0; - OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true; - OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true; - writel(OutboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_GEM_OutboundDoorBellRegisterClearOffset); -} - -static inline -bool DAC960_GEM_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) -{ - DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = - readl(ControllerBaseAddress + - DAC960_GEM_OutboundDoorBellRegisterReadSetOffset); - return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable; -} - -static inline -bool DAC960_GEM_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) -{ - DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = - readl(ControllerBaseAddress + - DAC960_GEM_OutboundDoorBellRegisterReadSetOffset); - return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable; -} - -static inline -void DAC960_GEM_EnableInterrupts(void __iomem *ControllerBaseAddress) -{ - DAC960_GEM_InterruptMaskRegister_T InterruptMaskRegister; - InterruptMaskRegister.All = 0; - InterruptMaskRegister.Bits.HardwareMailboxInterrupt = true; - InterruptMaskRegister.Bits.MemoryMailboxInterrupt = true; - writel(InterruptMaskRegister.All, - ControllerBaseAddress + DAC960_GEM_InterruptMaskRegisterClearOffset); -} - -static inline -void DAC960_GEM_DisableInterrupts(void __iomem *ControllerBaseAddress) -{ - DAC960_GEM_InterruptMaskRegister_T InterruptMaskRegister; - InterruptMaskRegister.All = 0; - InterruptMaskRegister.Bits.HardwareMailboxInterrupt = true; - InterruptMaskRegister.Bits.MemoryMailboxInterrupt = true; - writel(InterruptMaskRegister.All, - ControllerBaseAddress + DAC960_GEM_InterruptMaskRegisterReadSetOffset); -} - -static inline -bool DAC960_GEM_InterruptsEnabledP(void __iomem *ControllerBaseAddress) -{ - DAC960_GEM_InterruptMaskRegister_T InterruptMaskRegister; - InterruptMaskRegister.All = - readl(ControllerBaseAddress + - DAC960_GEM_InterruptMaskRegisterReadSetOffset); - return !(InterruptMaskRegister.Bits.HardwareMailboxInterrupt || - InterruptMaskRegister.Bits.MemoryMailboxInterrupt); -} - -static inline -void DAC960_GEM_WriteCommandMailbox(DAC960_V2_CommandMailbox_T - *MemoryCommandMailbox, - DAC960_V2_CommandMailbox_T - *CommandMailbox) -{ - memcpy(&MemoryCommandMailbox->Words[1], &CommandMailbox->Words[1], - sizeof(DAC960_V2_CommandMailbox_T) - sizeof(unsigned int)); - wmb(); - MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0]; - mb(); -} - -static inline -void DAC960_GEM_WriteHardwareMailbox(void __iomem *ControllerBaseAddress, - dma_addr_t CommandMailboxDMA) -{ - dma_addr_writeql(CommandMailboxDMA, - ControllerBaseAddress + - DAC960_GEM_CommandMailboxBusAddressOffset); -} - -static inline DAC960_V2_CommandIdentifier_T -DAC960_GEM_ReadCommandIdentifier(void __iomem *ControllerBaseAddress) -{ - return readw(ControllerBaseAddress + DAC960_GEM_CommandStatusOffset); -} - -static inline DAC960_V2_CommandStatus_T -DAC960_GEM_ReadCommandStatus(void __iomem *ControllerBaseAddress) -{ - return readw(ControllerBaseAddress + DAC960_GEM_CommandStatusOffset + 2); -} - -static inline bool -DAC960_GEM_ReadErrorStatus(void __iomem *ControllerBaseAddress, - unsigned char *ErrorStatus, - unsigned char *Parameter0, - unsigned char *Parameter1) -{ - DAC960_GEM_ErrorStatusRegister_T ErrorStatusRegister; - ErrorStatusRegister.All = - readl(ControllerBaseAddress + DAC960_GEM_ErrorStatusRegisterReadSetOffset); - if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false; - ErrorStatusRegister.Bits.ErrorStatusPending = false; - *ErrorStatus = ErrorStatusRegister.All; - *Parameter0 = - readb(ControllerBaseAddress + DAC960_GEM_CommandMailboxBusAddressOffset + 0); - *Parameter1 = - readb(ControllerBaseAddress + DAC960_GEM_CommandMailboxBusAddressOffset + 1); - writel(0x03000000, ControllerBaseAddress + - DAC960_GEM_ErrorStatusRegisterClearOffset); - return true; -} - -/* - Define the DAC960 BA Series Controller Interface Register Offsets. -*/ - -#define DAC960_BA_RegisterWindowSize 0x80 - -typedef enum -{ - DAC960_BA_InboundDoorBellRegisterOffset = 0x60, - DAC960_BA_OutboundDoorBellRegisterOffset = 0x61, - DAC960_BA_InterruptStatusRegisterOffset = 0x30, - DAC960_BA_InterruptMaskRegisterOffset = 0x34, - DAC960_BA_CommandMailboxBusAddressOffset = 0x50, - DAC960_BA_CommandStatusOffset = 0x58, - DAC960_BA_ErrorStatusRegisterOffset = 0x63 -} -DAC960_BA_RegisterOffsets_T; - - -/* - Define the structure of the DAC960 BA Series Inbound Door Bell Register. -*/ - -typedef union DAC960_BA_InboundDoorBellRegister -{ - unsigned char All; - struct { - bool HardwareMailboxNewCommand:1; /* Bit 0 */ - bool AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */ - bool GenerateInterrupt:1; /* Bit 2 */ - bool ControllerReset:1; /* Bit 3 */ - bool MemoryMailboxNewCommand:1; /* Bit 4 */ - unsigned char :3; /* Bits 5-7 */ - } Write; - struct { - bool HardwareMailboxEmpty:1; /* Bit 0 */ - bool InitializationNotInProgress:1; /* Bit 1 */ - unsigned char :6; /* Bits 2-7 */ - } Read; -} -DAC960_BA_InboundDoorBellRegister_T; - - -/* - Define the structure of the DAC960 BA Series Outbound Door Bell Register. -*/ - -typedef union DAC960_BA_OutboundDoorBellRegister -{ - unsigned char All; - struct { - bool AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */ - bool AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */ - unsigned char :6; /* Bits 2-7 */ - } Write; - struct { - bool HardwareMailboxStatusAvailable:1; /* Bit 0 */ - bool MemoryMailboxStatusAvailable:1; /* Bit 1 */ - unsigned char :6; /* Bits 2-7 */ - } Read; -} -DAC960_BA_OutboundDoorBellRegister_T; - - -/* - Define the structure of the DAC960 BA Series Interrupt Mask Register. -*/ - -typedef union DAC960_BA_InterruptMaskRegister -{ - unsigned char All; - struct { - unsigned int :2; /* Bits 0-1 */ - bool DisableInterrupts:1; /* Bit 2 */ - bool DisableInterruptsI2O:1; /* Bit 3 */ - unsigned int :4; /* Bits 4-7 */ - } Bits; -} -DAC960_BA_InterruptMaskRegister_T; - - -/* - Define the structure of the DAC960 BA Series Error Status Register. -*/ - -typedef union DAC960_BA_ErrorStatusRegister -{ - unsigned char All; - struct { - unsigned int :2; /* Bits 0-1 */ - bool ErrorStatusPending:1; /* Bit 2 */ - unsigned int :5; /* Bits 3-7 */ - } Bits; -} -DAC960_BA_ErrorStatusRegister_T; - - -/* - Define inline functions to provide an abstraction for reading and writing the - DAC960 BA Series Controller Interface Registers. -*/ - -static inline -void DAC960_BA_HardwareMailboxNewCommand(void __iomem *ControllerBaseAddress) -{ - DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true; - writeb(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset); -} - -static inline -void DAC960_BA_AcknowledgeHardwareMailboxStatus(void __iomem *ControllerBaseAddress) -{ - DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true; - writeb(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset); -} - -static inline -void DAC960_BA_GenerateInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.GenerateInterrupt = true; - writeb(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset); -} - -static inline -void DAC960_BA_ControllerReset(void __iomem *ControllerBaseAddress) -{ - DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.ControllerReset = true; - writeb(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset); -} - -static inline -void DAC960_BA_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress) -{ - DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true; - writeb(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset); -} - -static inline -bool DAC960_BA_HardwareMailboxFullP(void __iomem *ControllerBaseAddress) -{ - DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = - readb(ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset); - return !InboundDoorBellRegister.Read.HardwareMailboxEmpty; -} - -static inline -bool DAC960_BA_InitializationInProgressP(void __iomem *ControllerBaseAddress) -{ - DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = - readb(ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset); - return !InboundDoorBellRegister.Read.InitializationNotInProgress; -} - -static inline -void DAC960_BA_AcknowledgeHardwareMailboxInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = 0; - OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true; - writeb(OutboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset); -} - -static inline -void DAC960_BA_AcknowledgeMemoryMailboxInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = 0; - OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true; - writeb(OutboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset); -} - -static inline -void DAC960_BA_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = 0; - OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true; - OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true; - writeb(OutboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset); -} - -static inline -bool DAC960_BA_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) -{ - DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = - readb(ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset); - return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable; -} - -static inline -bool DAC960_BA_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) -{ - DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = - readb(ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset); - return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable; -} - -static inline -void DAC960_BA_EnableInterrupts(void __iomem *ControllerBaseAddress) -{ - DAC960_BA_InterruptMaskRegister_T InterruptMaskRegister; - InterruptMaskRegister.All = 0xFF; - InterruptMaskRegister.Bits.DisableInterrupts = false; - InterruptMaskRegister.Bits.DisableInterruptsI2O = true; - writeb(InterruptMaskRegister.All, - ControllerBaseAddress + DAC960_BA_InterruptMaskRegisterOffset); -} - -static inline -void DAC960_BA_DisableInterrupts(void __iomem *ControllerBaseAddress) -{ - DAC960_BA_InterruptMaskRegister_T InterruptMaskRegister; - InterruptMaskRegister.All = 0xFF; - InterruptMaskRegister.Bits.DisableInterrupts = true; - InterruptMaskRegister.Bits.DisableInterruptsI2O = true; - writeb(InterruptMaskRegister.All, - ControllerBaseAddress + DAC960_BA_InterruptMaskRegisterOffset); -} - -static inline -bool DAC960_BA_InterruptsEnabledP(void __iomem *ControllerBaseAddress) -{ - DAC960_BA_InterruptMaskRegister_T InterruptMaskRegister; - InterruptMaskRegister.All = - readb(ControllerBaseAddress + DAC960_BA_InterruptMaskRegisterOffset); - return !InterruptMaskRegister.Bits.DisableInterrupts; -} - -static inline -void DAC960_BA_WriteCommandMailbox(DAC960_V2_CommandMailbox_T - *MemoryCommandMailbox, - DAC960_V2_CommandMailbox_T - *CommandMailbox) -{ - memcpy(&MemoryCommandMailbox->Words[1], &CommandMailbox->Words[1], - sizeof(DAC960_V2_CommandMailbox_T) - sizeof(unsigned int)); - wmb(); - MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0]; - mb(); -} - - -static inline -void DAC960_BA_WriteHardwareMailbox(void __iomem *ControllerBaseAddress, - dma_addr_t CommandMailboxDMA) -{ - dma_addr_writeql(CommandMailboxDMA, - ControllerBaseAddress + - DAC960_BA_CommandMailboxBusAddressOffset); -} - -static inline DAC960_V2_CommandIdentifier_T -DAC960_BA_ReadCommandIdentifier(void __iomem *ControllerBaseAddress) -{ - return readw(ControllerBaseAddress + DAC960_BA_CommandStatusOffset); -} - -static inline DAC960_V2_CommandStatus_T -DAC960_BA_ReadCommandStatus(void __iomem *ControllerBaseAddress) -{ - return readw(ControllerBaseAddress + DAC960_BA_CommandStatusOffset + 2); -} - -static inline bool -DAC960_BA_ReadErrorStatus(void __iomem *ControllerBaseAddress, - unsigned char *ErrorStatus, - unsigned char *Parameter0, - unsigned char *Parameter1) -{ - DAC960_BA_ErrorStatusRegister_T ErrorStatusRegister; - ErrorStatusRegister.All = - readb(ControllerBaseAddress + DAC960_BA_ErrorStatusRegisterOffset); - if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false; - ErrorStatusRegister.Bits.ErrorStatusPending = false; - *ErrorStatus = ErrorStatusRegister.All; - *Parameter0 = - readb(ControllerBaseAddress + DAC960_BA_CommandMailboxBusAddressOffset + 0); - *Parameter1 = - readb(ControllerBaseAddress + DAC960_BA_CommandMailboxBusAddressOffset + 1); - writeb(0xFF, ControllerBaseAddress + DAC960_BA_ErrorStatusRegisterOffset); - return true; -} - - -/* - Define the DAC960 LP Series Controller Interface Register Offsets. -*/ - -#define DAC960_LP_RegisterWindowSize 0x80 - -typedef enum -{ - DAC960_LP_InboundDoorBellRegisterOffset = 0x20, - DAC960_LP_OutboundDoorBellRegisterOffset = 0x2C, - DAC960_LP_InterruptStatusRegisterOffset = 0x30, - DAC960_LP_InterruptMaskRegisterOffset = 0x34, - DAC960_LP_CommandMailboxBusAddressOffset = 0x10, - DAC960_LP_CommandStatusOffset = 0x18, - DAC960_LP_ErrorStatusRegisterOffset = 0x2E -} -DAC960_LP_RegisterOffsets_T; - - -/* - Define the structure of the DAC960 LP Series Inbound Door Bell Register. -*/ - -typedef union DAC960_LP_InboundDoorBellRegister -{ - unsigned char All; - struct { - bool HardwareMailboxNewCommand:1; /* Bit 0 */ - bool AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */ - bool GenerateInterrupt:1; /* Bit 2 */ - bool ControllerReset:1; /* Bit 3 */ - bool MemoryMailboxNewCommand:1; /* Bit 4 */ - unsigned char :3; /* Bits 5-7 */ - } Write; - struct { - bool HardwareMailboxFull:1; /* Bit 0 */ - bool InitializationInProgress:1; /* Bit 1 */ - unsigned char :6; /* Bits 2-7 */ - } Read; -} -DAC960_LP_InboundDoorBellRegister_T; - - -/* - Define the structure of the DAC960 LP Series Outbound Door Bell Register. -*/ - -typedef union DAC960_LP_OutboundDoorBellRegister -{ - unsigned char All; - struct { - bool AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */ - bool AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */ - unsigned char :6; /* Bits 2-7 */ - } Write; - struct { - bool HardwareMailboxStatusAvailable:1; /* Bit 0 */ - bool MemoryMailboxStatusAvailable:1; /* Bit 1 */ - unsigned char :6; /* Bits 2-7 */ - } Read; -} -DAC960_LP_OutboundDoorBellRegister_T; - - -/* - Define the structure of the DAC960 LP Series Interrupt Mask Register. -*/ - -typedef union DAC960_LP_InterruptMaskRegister -{ - unsigned char All; - struct { - unsigned int :2; /* Bits 0-1 */ - bool DisableInterrupts:1; /* Bit 2 */ - unsigned int :5; /* Bits 3-7 */ - } Bits; -} -DAC960_LP_InterruptMaskRegister_T; - - -/* - Define the structure of the DAC960 LP Series Error Status Register. -*/ - -typedef union DAC960_LP_ErrorStatusRegister -{ - unsigned char All; - struct { - unsigned int :2; /* Bits 0-1 */ - bool ErrorStatusPending:1; /* Bit 2 */ - unsigned int :5; /* Bits 3-7 */ - } Bits; -} -DAC960_LP_ErrorStatusRegister_T; - - -/* - Define inline functions to provide an abstraction for reading and writing the - DAC960 LP Series Controller Interface Registers. -*/ - -static inline -void DAC960_LP_HardwareMailboxNewCommand(void __iomem *ControllerBaseAddress) -{ - DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true; - writeb(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset); -} - -static inline -void DAC960_LP_AcknowledgeHardwareMailboxStatus(void __iomem *ControllerBaseAddress) -{ - DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true; - writeb(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset); -} - -static inline -void DAC960_LP_GenerateInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.GenerateInterrupt = true; - writeb(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset); -} - -static inline -void DAC960_LP_ControllerReset(void __iomem *ControllerBaseAddress) -{ - DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.ControllerReset = true; - writeb(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset); -} - -static inline -void DAC960_LP_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress) -{ - DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true; - writeb(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset); -} - -static inline -bool DAC960_LP_HardwareMailboxFullP(void __iomem *ControllerBaseAddress) -{ - DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = - readb(ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset); - return InboundDoorBellRegister.Read.HardwareMailboxFull; -} - -static inline -bool DAC960_LP_InitializationInProgressP(void __iomem *ControllerBaseAddress) -{ - DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = - readb(ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset); - return InboundDoorBellRegister.Read.InitializationInProgress; -} - -static inline -void DAC960_LP_AcknowledgeHardwareMailboxInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = 0; - OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true; - writeb(OutboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset); -} - -static inline -void DAC960_LP_AcknowledgeMemoryMailboxInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = 0; - OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true; - writeb(OutboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset); -} - -static inline -void DAC960_LP_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = 0; - OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true; - OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true; - writeb(OutboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset); -} - -static inline -bool DAC960_LP_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) -{ - DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = - readb(ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset); - return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable; -} - -static inline -bool DAC960_LP_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) -{ - DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = - readb(ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset); - return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable; -} - -static inline -void DAC960_LP_EnableInterrupts(void __iomem *ControllerBaseAddress) -{ - DAC960_LP_InterruptMaskRegister_T InterruptMaskRegister; - InterruptMaskRegister.All = 0xFF; - InterruptMaskRegister.Bits.DisableInterrupts = false; - writeb(InterruptMaskRegister.All, - ControllerBaseAddress + DAC960_LP_InterruptMaskRegisterOffset); -} - -static inline -void DAC960_LP_DisableInterrupts(void __iomem *ControllerBaseAddress) -{ - DAC960_LP_InterruptMaskRegister_T InterruptMaskRegister; - InterruptMaskRegister.All = 0xFF; - InterruptMaskRegister.Bits.DisableInterrupts = true; - writeb(InterruptMaskRegister.All, - ControllerBaseAddress + DAC960_LP_InterruptMaskRegisterOffset); -} - -static inline -bool DAC960_LP_InterruptsEnabledP(void __iomem *ControllerBaseAddress) -{ - DAC960_LP_InterruptMaskRegister_T InterruptMaskRegister; - InterruptMaskRegister.All = - readb(ControllerBaseAddress + DAC960_LP_InterruptMaskRegisterOffset); - return !InterruptMaskRegister.Bits.DisableInterrupts; -} - -static inline -void DAC960_LP_WriteCommandMailbox(DAC960_V2_CommandMailbox_T - *MemoryCommandMailbox, - DAC960_V2_CommandMailbox_T - *CommandMailbox) -{ - memcpy(&MemoryCommandMailbox->Words[1], &CommandMailbox->Words[1], - sizeof(DAC960_V2_CommandMailbox_T) - sizeof(unsigned int)); - wmb(); - MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0]; - mb(); -} - -static inline -void DAC960_LP_WriteHardwareMailbox(void __iomem *ControllerBaseAddress, - dma_addr_t CommandMailboxDMA) -{ - dma_addr_writeql(CommandMailboxDMA, - ControllerBaseAddress + - DAC960_LP_CommandMailboxBusAddressOffset); -} - -static inline DAC960_V2_CommandIdentifier_T -DAC960_LP_ReadCommandIdentifier(void __iomem *ControllerBaseAddress) -{ - return readw(ControllerBaseAddress + DAC960_LP_CommandStatusOffset); -} - -static inline DAC960_V2_CommandStatus_T -DAC960_LP_ReadCommandStatus(void __iomem *ControllerBaseAddress) -{ - return readw(ControllerBaseAddress + DAC960_LP_CommandStatusOffset + 2); -} - -static inline bool -DAC960_LP_ReadErrorStatus(void __iomem *ControllerBaseAddress, - unsigned char *ErrorStatus, - unsigned char *Parameter0, - unsigned char *Parameter1) -{ - DAC960_LP_ErrorStatusRegister_T ErrorStatusRegister; - ErrorStatusRegister.All = - readb(ControllerBaseAddress + DAC960_LP_ErrorStatusRegisterOffset); - if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false; - ErrorStatusRegister.Bits.ErrorStatusPending = false; - *ErrorStatus = ErrorStatusRegister.All; - *Parameter0 = - readb(ControllerBaseAddress + DAC960_LP_CommandMailboxBusAddressOffset + 0); - *Parameter1 = - readb(ControllerBaseAddress + DAC960_LP_CommandMailboxBusAddressOffset + 1); - writeb(0xFF, ControllerBaseAddress + DAC960_LP_ErrorStatusRegisterOffset); - return true; -} - - -/* - Define the DAC960 LA Series Controller Interface Register Offsets. -*/ - -#define DAC960_LA_RegisterWindowSize 0x80 - -typedef enum -{ - DAC960_LA_InboundDoorBellRegisterOffset = 0x60, - DAC960_LA_OutboundDoorBellRegisterOffset = 0x61, - DAC960_LA_InterruptMaskRegisterOffset = 0x34, - DAC960_LA_CommandOpcodeRegisterOffset = 0x50, - DAC960_LA_CommandIdentifierRegisterOffset = 0x51, - DAC960_LA_MailboxRegister2Offset = 0x52, - DAC960_LA_MailboxRegister3Offset = 0x53, - DAC960_LA_MailboxRegister4Offset = 0x54, - DAC960_LA_MailboxRegister5Offset = 0x55, - DAC960_LA_MailboxRegister6Offset = 0x56, - DAC960_LA_MailboxRegister7Offset = 0x57, - DAC960_LA_MailboxRegister8Offset = 0x58, - DAC960_LA_MailboxRegister9Offset = 0x59, - DAC960_LA_MailboxRegister10Offset = 0x5A, - DAC960_LA_MailboxRegister11Offset = 0x5B, - DAC960_LA_MailboxRegister12Offset = 0x5C, - DAC960_LA_StatusCommandIdentifierRegOffset = 0x5D, - DAC960_LA_StatusRegisterOffset = 0x5E, - DAC960_LA_ErrorStatusRegisterOffset = 0x63 -} -DAC960_LA_RegisterOffsets_T; - - -/* - Define the structure of the DAC960 LA Series Inbound Door Bell Register. -*/ - -typedef union DAC960_LA_InboundDoorBellRegister -{ - unsigned char All; - struct { - bool HardwareMailboxNewCommand:1; /* Bit 0 */ - bool AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */ - bool GenerateInterrupt:1; /* Bit 2 */ - bool ControllerReset:1; /* Bit 3 */ - bool MemoryMailboxNewCommand:1; /* Bit 4 */ - unsigned char :3; /* Bits 5-7 */ - } Write; - struct { - bool HardwareMailboxEmpty:1; /* Bit 0 */ - bool InitializationNotInProgress:1; /* Bit 1 */ - unsigned char :6; /* Bits 2-7 */ - } Read; -} -DAC960_LA_InboundDoorBellRegister_T; - - -/* - Define the structure of the DAC960 LA Series Outbound Door Bell Register. -*/ - -typedef union DAC960_LA_OutboundDoorBellRegister -{ - unsigned char All; - struct { - bool AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */ - bool AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */ - unsigned char :6; /* Bits 2-7 */ - } Write; - struct { - bool HardwareMailboxStatusAvailable:1; /* Bit 0 */ - bool MemoryMailboxStatusAvailable:1; /* Bit 1 */ - unsigned char :6; /* Bits 2-7 */ - } Read; -} -DAC960_LA_OutboundDoorBellRegister_T; - - -/* - Define the structure of the DAC960 LA Series Interrupt Mask Register. -*/ - -typedef union DAC960_LA_InterruptMaskRegister -{ - unsigned char All; - struct { - unsigned char :2; /* Bits 0-1 */ - bool DisableInterrupts:1; /* Bit 2 */ - unsigned char :5; /* Bits 3-7 */ - } Bits; -} -DAC960_LA_InterruptMaskRegister_T; - - -/* - Define the structure of the DAC960 LA Series Error Status Register. -*/ - -typedef union DAC960_LA_ErrorStatusRegister -{ - unsigned char All; - struct { - unsigned int :2; /* Bits 0-1 */ - bool ErrorStatusPending:1; /* Bit 2 */ - unsigned int :5; /* Bits 3-7 */ - } Bits; -} -DAC960_LA_ErrorStatusRegister_T; - - -/* - Define inline functions to provide an abstraction for reading and writing the - DAC960 LA Series Controller Interface Registers. -*/ - -static inline -void DAC960_LA_HardwareMailboxNewCommand(void __iomem *ControllerBaseAddress) -{ - DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true; - writeb(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset); -} - -static inline -void DAC960_LA_AcknowledgeHardwareMailboxStatus(void __iomem *ControllerBaseAddress) -{ - DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true; - writeb(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset); -} - -static inline -void DAC960_LA_GenerateInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.GenerateInterrupt = true; - writeb(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset); -} - -static inline -void DAC960_LA_ControllerReset(void __iomem *ControllerBaseAddress) -{ - DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.ControllerReset = true; - writeb(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset); -} - -static inline -void DAC960_LA_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress) -{ - DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true; - writeb(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset); -} - -static inline -bool DAC960_LA_HardwareMailboxFullP(void __iomem *ControllerBaseAddress) -{ - DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = - readb(ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset); - return !InboundDoorBellRegister.Read.HardwareMailboxEmpty; -} - -static inline -bool DAC960_LA_InitializationInProgressP(void __iomem *ControllerBaseAddress) -{ - DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = - readb(ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset); - return !InboundDoorBellRegister.Read.InitializationNotInProgress; -} - -static inline -void DAC960_LA_AcknowledgeHardwareMailboxInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = 0; - OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true; - writeb(OutboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset); -} - -static inline -void DAC960_LA_AcknowledgeMemoryMailboxInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = 0; - OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true; - writeb(OutboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset); -} - -static inline -void DAC960_LA_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = 0; - OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true; - OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true; - writeb(OutboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset); -} - -static inline -bool DAC960_LA_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) -{ - DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = - readb(ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset); - return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable; -} - -static inline -bool DAC960_LA_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) -{ - DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = - readb(ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset); - return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable; -} - -static inline -void DAC960_LA_EnableInterrupts(void __iomem *ControllerBaseAddress) -{ - DAC960_LA_InterruptMaskRegister_T InterruptMaskRegister; - InterruptMaskRegister.All = 0xFF; - InterruptMaskRegister.Bits.DisableInterrupts = false; - writeb(InterruptMaskRegister.All, - ControllerBaseAddress + DAC960_LA_InterruptMaskRegisterOffset); -} - -static inline -void DAC960_LA_DisableInterrupts(void __iomem *ControllerBaseAddress) -{ - DAC960_LA_InterruptMaskRegister_T InterruptMaskRegister; - InterruptMaskRegister.All = 0xFF; - InterruptMaskRegister.Bits.DisableInterrupts = true; - writeb(InterruptMaskRegister.All, - ControllerBaseAddress + DAC960_LA_InterruptMaskRegisterOffset); -} - -static inline -bool DAC960_LA_InterruptsEnabledP(void __iomem *ControllerBaseAddress) -{ - DAC960_LA_InterruptMaskRegister_T InterruptMaskRegister; - InterruptMaskRegister.All = - readb(ControllerBaseAddress + DAC960_LA_InterruptMaskRegisterOffset); - return !InterruptMaskRegister.Bits.DisableInterrupts; -} - -static inline -void DAC960_LA_WriteCommandMailbox(DAC960_V1_CommandMailbox_T - *MemoryCommandMailbox, - DAC960_V1_CommandMailbox_T - *CommandMailbox) -{ - MemoryCommandMailbox->Words[1] = CommandMailbox->Words[1]; - MemoryCommandMailbox->Words[2] = CommandMailbox->Words[2]; - MemoryCommandMailbox->Words[3] = CommandMailbox->Words[3]; - wmb(); - MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0]; - mb(); -} - -static inline -void DAC960_LA_WriteHardwareMailbox(void __iomem *ControllerBaseAddress, - DAC960_V1_CommandMailbox_T *CommandMailbox) -{ - writel(CommandMailbox->Words[0], - ControllerBaseAddress + DAC960_LA_CommandOpcodeRegisterOffset); - writel(CommandMailbox->Words[1], - ControllerBaseAddress + DAC960_LA_MailboxRegister4Offset); - writel(CommandMailbox->Words[2], - ControllerBaseAddress + DAC960_LA_MailboxRegister8Offset); - writeb(CommandMailbox->Bytes[12], - ControllerBaseAddress + DAC960_LA_MailboxRegister12Offset); -} - -static inline DAC960_V1_CommandIdentifier_T -DAC960_LA_ReadStatusCommandIdentifier(void __iomem *ControllerBaseAddress) -{ - return readb(ControllerBaseAddress - + DAC960_LA_StatusCommandIdentifierRegOffset); -} - -static inline DAC960_V1_CommandStatus_T -DAC960_LA_ReadStatusRegister(void __iomem *ControllerBaseAddress) -{ - return readw(ControllerBaseAddress + DAC960_LA_StatusRegisterOffset); -} - -static inline bool -DAC960_LA_ReadErrorStatus(void __iomem *ControllerBaseAddress, - unsigned char *ErrorStatus, - unsigned char *Parameter0, - unsigned char *Parameter1) -{ - DAC960_LA_ErrorStatusRegister_T ErrorStatusRegister; - ErrorStatusRegister.All = - readb(ControllerBaseAddress + DAC960_LA_ErrorStatusRegisterOffset); - if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false; - ErrorStatusRegister.Bits.ErrorStatusPending = false; - *ErrorStatus = ErrorStatusRegister.All; - *Parameter0 = - readb(ControllerBaseAddress + DAC960_LA_CommandOpcodeRegisterOffset); - *Parameter1 = - readb(ControllerBaseAddress + DAC960_LA_CommandIdentifierRegisterOffset); - writeb(0xFF, ControllerBaseAddress + DAC960_LA_ErrorStatusRegisterOffset); - return true; -} - -/* - Define the DAC960 PG Series Controller Interface Register Offsets. -*/ - -#define DAC960_PG_RegisterWindowSize 0x2000 - -typedef enum -{ - DAC960_PG_InboundDoorBellRegisterOffset = 0x0020, - DAC960_PG_OutboundDoorBellRegisterOffset = 0x002C, - DAC960_PG_InterruptMaskRegisterOffset = 0x0034, - DAC960_PG_CommandOpcodeRegisterOffset = 0x1000, - DAC960_PG_CommandIdentifierRegisterOffset = 0x1001, - DAC960_PG_MailboxRegister2Offset = 0x1002, - DAC960_PG_MailboxRegister3Offset = 0x1003, - DAC960_PG_MailboxRegister4Offset = 0x1004, - DAC960_PG_MailboxRegister5Offset = 0x1005, - DAC960_PG_MailboxRegister6Offset = 0x1006, - DAC960_PG_MailboxRegister7Offset = 0x1007, - DAC960_PG_MailboxRegister8Offset = 0x1008, - DAC960_PG_MailboxRegister9Offset = 0x1009, - DAC960_PG_MailboxRegister10Offset = 0x100A, - DAC960_PG_MailboxRegister11Offset = 0x100B, - DAC960_PG_MailboxRegister12Offset = 0x100C, - DAC960_PG_StatusCommandIdentifierRegOffset = 0x1018, - DAC960_PG_StatusRegisterOffset = 0x101A, - DAC960_PG_ErrorStatusRegisterOffset = 0x103F -} -DAC960_PG_RegisterOffsets_T; - - -/* - Define the structure of the DAC960 PG Series Inbound Door Bell Register. -*/ - -typedef union DAC960_PG_InboundDoorBellRegister -{ - unsigned int All; - struct { - bool HardwareMailboxNewCommand:1; /* Bit 0 */ - bool AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */ - bool GenerateInterrupt:1; /* Bit 2 */ - bool ControllerReset:1; /* Bit 3 */ - bool MemoryMailboxNewCommand:1; /* Bit 4 */ - unsigned int :27; /* Bits 5-31 */ - } Write; - struct { - bool HardwareMailboxFull:1; /* Bit 0 */ - bool InitializationInProgress:1; /* Bit 1 */ - unsigned int :30; /* Bits 2-31 */ - } Read; -} -DAC960_PG_InboundDoorBellRegister_T; - - -/* - Define the structure of the DAC960 PG Series Outbound Door Bell Register. -*/ - -typedef union DAC960_PG_OutboundDoorBellRegister -{ - unsigned int All; - struct { - bool AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */ - bool AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */ - unsigned int :30; /* Bits 2-31 */ - } Write; - struct { - bool HardwareMailboxStatusAvailable:1; /* Bit 0 */ - bool MemoryMailboxStatusAvailable:1; /* Bit 1 */ - unsigned int :30; /* Bits 2-31 */ - } Read; -} -DAC960_PG_OutboundDoorBellRegister_T; - - -/* - Define the structure of the DAC960 PG Series Interrupt Mask Register. -*/ - -typedef union DAC960_PG_InterruptMaskRegister -{ - unsigned int All; - struct { - unsigned int MessageUnitInterruptMask1:2; /* Bits 0-1 */ - bool DisableInterrupts:1; /* Bit 2 */ - unsigned int MessageUnitInterruptMask2:5; /* Bits 3-7 */ - unsigned int Reserved0:24; /* Bits 8-31 */ - } Bits; -} -DAC960_PG_InterruptMaskRegister_T; - - -/* - Define the structure of the DAC960 PG Series Error Status Register. -*/ - -typedef union DAC960_PG_ErrorStatusRegister -{ - unsigned char All; - struct { - unsigned int :2; /* Bits 0-1 */ - bool ErrorStatusPending:1; /* Bit 2 */ - unsigned int :5; /* Bits 3-7 */ - } Bits; -} -DAC960_PG_ErrorStatusRegister_T; - - -/* - Define inline functions to provide an abstraction for reading and writing the - DAC960 PG Series Controller Interface Registers. -*/ - -static inline -void DAC960_PG_HardwareMailboxNewCommand(void __iomem *ControllerBaseAddress) -{ - DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true; - writel(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset); -} - -static inline -void DAC960_PG_AcknowledgeHardwareMailboxStatus(void __iomem *ControllerBaseAddress) -{ - DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true; - writel(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset); -} - -static inline -void DAC960_PG_GenerateInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.GenerateInterrupt = true; - writel(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset); -} - -static inline -void DAC960_PG_ControllerReset(void __iomem *ControllerBaseAddress) -{ - DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.ControllerReset = true; - writel(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset); -} - -static inline -void DAC960_PG_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress) -{ - DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true; - writel(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset); -} - -static inline -bool DAC960_PG_HardwareMailboxFullP(void __iomem *ControllerBaseAddress) -{ - DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = - readl(ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset); - return InboundDoorBellRegister.Read.HardwareMailboxFull; -} - -static inline -bool DAC960_PG_InitializationInProgressP(void __iomem *ControllerBaseAddress) -{ - DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = - readl(ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset); - return InboundDoorBellRegister.Read.InitializationInProgress; -} - -static inline -void DAC960_PG_AcknowledgeHardwareMailboxInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = 0; - OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true; - writel(OutboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset); -} - -static inline -void DAC960_PG_AcknowledgeMemoryMailboxInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = 0; - OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true; - writel(OutboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset); -} - -static inline -void DAC960_PG_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = 0; - OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true; - OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true; - writel(OutboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset); -} - -static inline -bool DAC960_PG_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) -{ - DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = - readl(ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset); - return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable; -} - -static inline -bool DAC960_PG_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) -{ - DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = - readl(ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset); - return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable; -} - -static inline -void DAC960_PG_EnableInterrupts(void __iomem *ControllerBaseAddress) -{ - DAC960_PG_InterruptMaskRegister_T InterruptMaskRegister; - InterruptMaskRegister.All = 0; - InterruptMaskRegister.Bits.MessageUnitInterruptMask1 = 0x3; - InterruptMaskRegister.Bits.DisableInterrupts = false; - InterruptMaskRegister.Bits.MessageUnitInterruptMask2 = 0x1F; - writel(InterruptMaskRegister.All, - ControllerBaseAddress + DAC960_PG_InterruptMaskRegisterOffset); -} - -static inline -void DAC960_PG_DisableInterrupts(void __iomem *ControllerBaseAddress) -{ - DAC960_PG_InterruptMaskRegister_T InterruptMaskRegister; - InterruptMaskRegister.All = 0; - InterruptMaskRegister.Bits.MessageUnitInterruptMask1 = 0x3; - InterruptMaskRegister.Bits.DisableInterrupts = true; - InterruptMaskRegister.Bits.MessageUnitInterruptMask2 = 0x1F; - writel(InterruptMaskRegister.All, - ControllerBaseAddress + DAC960_PG_InterruptMaskRegisterOffset); -} - -static inline -bool DAC960_PG_InterruptsEnabledP(void __iomem *ControllerBaseAddress) -{ - DAC960_PG_InterruptMaskRegister_T InterruptMaskRegister; - InterruptMaskRegister.All = - readl(ControllerBaseAddress + DAC960_PG_InterruptMaskRegisterOffset); - return !InterruptMaskRegister.Bits.DisableInterrupts; -} - -static inline -void DAC960_PG_WriteCommandMailbox(DAC960_V1_CommandMailbox_T - *MemoryCommandMailbox, - DAC960_V1_CommandMailbox_T - *CommandMailbox) -{ - MemoryCommandMailbox->Words[1] = CommandMailbox->Words[1]; - MemoryCommandMailbox->Words[2] = CommandMailbox->Words[2]; - MemoryCommandMailbox->Words[3] = CommandMailbox->Words[3]; - wmb(); - MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0]; - mb(); -} - -static inline -void DAC960_PG_WriteHardwareMailbox(void __iomem *ControllerBaseAddress, - DAC960_V1_CommandMailbox_T *CommandMailbox) -{ - writel(CommandMailbox->Words[0], - ControllerBaseAddress + DAC960_PG_CommandOpcodeRegisterOffset); - writel(CommandMailbox->Words[1], - ControllerBaseAddress + DAC960_PG_MailboxRegister4Offset); - writel(CommandMailbox->Words[2], - ControllerBaseAddress + DAC960_PG_MailboxRegister8Offset); - writeb(CommandMailbox->Bytes[12], - ControllerBaseAddress + DAC960_PG_MailboxRegister12Offset); -} - -static inline DAC960_V1_CommandIdentifier_T -DAC960_PG_ReadStatusCommandIdentifier(void __iomem *ControllerBaseAddress) -{ - return readb(ControllerBaseAddress - + DAC960_PG_StatusCommandIdentifierRegOffset); -} - -static inline DAC960_V1_CommandStatus_T -DAC960_PG_ReadStatusRegister(void __iomem *ControllerBaseAddress) -{ - return readw(ControllerBaseAddress + DAC960_PG_StatusRegisterOffset); -} - -static inline bool -DAC960_PG_ReadErrorStatus(void __iomem *ControllerBaseAddress, - unsigned char *ErrorStatus, - unsigned char *Parameter0, - unsigned char *Parameter1) -{ - DAC960_PG_ErrorStatusRegister_T ErrorStatusRegister; - ErrorStatusRegister.All = - readb(ControllerBaseAddress + DAC960_PG_ErrorStatusRegisterOffset); - if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false; - ErrorStatusRegister.Bits.ErrorStatusPending = false; - *ErrorStatus = ErrorStatusRegister.All; - *Parameter0 = - readb(ControllerBaseAddress + DAC960_PG_CommandOpcodeRegisterOffset); - *Parameter1 = - readb(ControllerBaseAddress + DAC960_PG_CommandIdentifierRegisterOffset); - writeb(0, ControllerBaseAddress + DAC960_PG_ErrorStatusRegisterOffset); - return true; -} - -/* - Define the DAC960 PD Series Controller Interface Register Offsets. -*/ - -#define DAC960_PD_RegisterWindowSize 0x80 - -typedef enum -{ - DAC960_PD_CommandOpcodeRegisterOffset = 0x00, - DAC960_PD_CommandIdentifierRegisterOffset = 0x01, - DAC960_PD_MailboxRegister2Offset = 0x02, - DAC960_PD_MailboxRegister3Offset = 0x03, - DAC960_PD_MailboxRegister4Offset = 0x04, - DAC960_PD_MailboxRegister5Offset = 0x05, - DAC960_PD_MailboxRegister6Offset = 0x06, - DAC960_PD_MailboxRegister7Offset = 0x07, - DAC960_PD_MailboxRegister8Offset = 0x08, - DAC960_PD_MailboxRegister9Offset = 0x09, - DAC960_PD_MailboxRegister10Offset = 0x0A, - DAC960_PD_MailboxRegister11Offset = 0x0B, - DAC960_PD_MailboxRegister12Offset = 0x0C, - DAC960_PD_StatusCommandIdentifierRegOffset = 0x0D, - DAC960_PD_StatusRegisterOffset = 0x0E, - DAC960_PD_ErrorStatusRegisterOffset = 0x3F, - DAC960_PD_InboundDoorBellRegisterOffset = 0x40, - DAC960_PD_OutboundDoorBellRegisterOffset = 0x41, - DAC960_PD_InterruptEnableRegisterOffset = 0x43 -} -DAC960_PD_RegisterOffsets_T; - - -/* - Define the structure of the DAC960 PD Series Inbound Door Bell Register. -*/ - -typedef union DAC960_PD_InboundDoorBellRegister -{ - unsigned char All; - struct { - bool NewCommand:1; /* Bit 0 */ - bool AcknowledgeStatus:1; /* Bit 1 */ - bool GenerateInterrupt:1; /* Bit 2 */ - bool ControllerReset:1; /* Bit 3 */ - unsigned char :4; /* Bits 4-7 */ - } Write; - struct { - bool MailboxFull:1; /* Bit 0 */ - bool InitializationInProgress:1; /* Bit 1 */ - unsigned char :6; /* Bits 2-7 */ - } Read; -} -DAC960_PD_InboundDoorBellRegister_T; - - -/* - Define the structure of the DAC960 PD Series Outbound Door Bell Register. -*/ - -typedef union DAC960_PD_OutboundDoorBellRegister -{ - unsigned char All; - struct { - bool AcknowledgeInterrupt:1; /* Bit 0 */ - unsigned char :7; /* Bits 1-7 */ - } Write; - struct { - bool StatusAvailable:1; /* Bit 0 */ - unsigned char :7; /* Bits 1-7 */ - } Read; -} -DAC960_PD_OutboundDoorBellRegister_T; - - -/* - Define the structure of the DAC960 PD Series Interrupt Enable Register. -*/ - -typedef union DAC960_PD_InterruptEnableRegister -{ - unsigned char All; - struct { - bool EnableInterrupts:1; /* Bit 0 */ - unsigned char :7; /* Bits 1-7 */ - } Bits; -} -DAC960_PD_InterruptEnableRegister_T; - - -/* - Define the structure of the DAC960 PD Series Error Status Register. -*/ - -typedef union DAC960_PD_ErrorStatusRegister -{ - unsigned char All; - struct { - unsigned int :2; /* Bits 0-1 */ - bool ErrorStatusPending:1; /* Bit 2 */ - unsigned int :5; /* Bits 3-7 */ - } Bits; -} -DAC960_PD_ErrorStatusRegister_T; - - -/* - Define inline functions to provide an abstraction for reading and writing the - DAC960 PD Series Controller Interface Registers. -*/ - -static inline -void DAC960_PD_NewCommand(void __iomem *ControllerBaseAddress) -{ - DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.NewCommand = true; - writeb(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset); -} - -static inline -void DAC960_PD_AcknowledgeStatus(void __iomem *ControllerBaseAddress) -{ - DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.AcknowledgeStatus = true; - writeb(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset); -} - -static inline -void DAC960_PD_GenerateInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.GenerateInterrupt = true; - writeb(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset); -} - -static inline -void DAC960_PD_ControllerReset(void __iomem *ControllerBaseAddress) -{ - DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = 0; - InboundDoorBellRegister.Write.ControllerReset = true; - writeb(InboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset); -} - -static inline -bool DAC960_PD_MailboxFullP(void __iomem *ControllerBaseAddress) -{ - DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = - readb(ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset); - return InboundDoorBellRegister.Read.MailboxFull; -} - -static inline -bool DAC960_PD_InitializationInProgressP(void __iomem *ControllerBaseAddress) -{ - DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister; - InboundDoorBellRegister.All = - readb(ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset); - return InboundDoorBellRegister.Read.InitializationInProgress; -} - -static inline -void DAC960_PD_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress) -{ - DAC960_PD_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = 0; - OutboundDoorBellRegister.Write.AcknowledgeInterrupt = true; - writeb(OutboundDoorBellRegister.All, - ControllerBaseAddress + DAC960_PD_OutboundDoorBellRegisterOffset); -} - -static inline -bool DAC960_PD_StatusAvailableP(void __iomem *ControllerBaseAddress) -{ - DAC960_PD_OutboundDoorBellRegister_T OutboundDoorBellRegister; - OutboundDoorBellRegister.All = - readb(ControllerBaseAddress + DAC960_PD_OutboundDoorBellRegisterOffset); - return OutboundDoorBellRegister.Read.StatusAvailable; -} - -static inline -void DAC960_PD_EnableInterrupts(void __iomem *ControllerBaseAddress) -{ - DAC960_PD_InterruptEnableRegister_T InterruptEnableRegister; - InterruptEnableRegister.All = 0; - InterruptEnableRegister.Bits.EnableInterrupts = true; - writeb(InterruptEnableRegister.All, - ControllerBaseAddress + DAC960_PD_InterruptEnableRegisterOffset); -} - -static inline -void DAC960_PD_DisableInterrupts(void __iomem *ControllerBaseAddress) -{ - DAC960_PD_InterruptEnableRegister_T InterruptEnableRegister; - InterruptEnableRegister.All = 0; - InterruptEnableRegister.Bits.EnableInterrupts = false; - writeb(InterruptEnableRegister.All, - ControllerBaseAddress + DAC960_PD_InterruptEnableRegisterOffset); -} - -static inline -bool DAC960_PD_InterruptsEnabledP(void __iomem *ControllerBaseAddress) -{ - DAC960_PD_InterruptEnableRegister_T InterruptEnableRegister; - InterruptEnableRegister.All = - readb(ControllerBaseAddress + DAC960_PD_InterruptEnableRegisterOffset); - return InterruptEnableRegister.Bits.EnableInterrupts; -} - -static inline -void DAC960_PD_WriteCommandMailbox(void __iomem *ControllerBaseAddress, - DAC960_V1_CommandMailbox_T *CommandMailbox) -{ - writel(CommandMailbox->Words[0], - ControllerBaseAddress + DAC960_PD_CommandOpcodeRegisterOffset); - writel(CommandMailbox->Words[1], - ControllerBaseAddress + DAC960_PD_MailboxRegister4Offset); - writel(CommandMailbox->Words[2], - ControllerBaseAddress + DAC960_PD_MailboxRegister8Offset); - writeb(CommandMailbox->Bytes[12], - ControllerBaseAddress + DAC960_PD_MailboxRegister12Offset); -} - -static inline DAC960_V1_CommandIdentifier_T -DAC960_PD_ReadStatusCommandIdentifier(void __iomem *ControllerBaseAddress) -{ - return readb(ControllerBaseAddress - + DAC960_PD_StatusCommandIdentifierRegOffset); -} - -static inline DAC960_V1_CommandStatus_T -DAC960_PD_ReadStatusRegister(void __iomem *ControllerBaseAddress) -{ - return readw(ControllerBaseAddress + DAC960_PD_StatusRegisterOffset); -} - -static inline bool -DAC960_PD_ReadErrorStatus(void __iomem *ControllerBaseAddress, - unsigned char *ErrorStatus, - unsigned char *Parameter0, - unsigned char *Parameter1) -{ - DAC960_PD_ErrorStatusRegister_T ErrorStatusRegister; - ErrorStatusRegister.All = - readb(ControllerBaseAddress + DAC960_PD_ErrorStatusRegisterOffset); - if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false; - ErrorStatusRegister.Bits.ErrorStatusPending = false; - *ErrorStatus = ErrorStatusRegister.All; - *Parameter0 = - readb(ControllerBaseAddress + DAC960_PD_CommandOpcodeRegisterOffset); - *Parameter1 = - readb(ControllerBaseAddress + DAC960_PD_CommandIdentifierRegisterOffset); - writeb(0, ControllerBaseAddress + DAC960_PD_ErrorStatusRegisterOffset); - return true; -} - -static inline void DAC960_P_To_PD_TranslateEnquiry(void *Enquiry) -{ - memcpy(Enquiry + 132, Enquiry + 36, 64); - memset(Enquiry + 36, 0, 96); -} - -static inline void DAC960_P_To_PD_TranslateDeviceState(void *DeviceState) -{ - memcpy(DeviceState + 2, DeviceState + 3, 1); - memmove(DeviceState + 4, DeviceState + 5, 2); - memmove(DeviceState + 6, DeviceState + 8, 4); -} - -static inline -void DAC960_PD_To_P_TranslateReadWriteCommand(DAC960_V1_CommandMailbox_T - *CommandMailbox) -{ - int LogicalDriveNumber = CommandMailbox->Type5.LD.LogicalDriveNumber; - CommandMailbox->Bytes[3] &= 0x7; - CommandMailbox->Bytes[3] |= CommandMailbox->Bytes[7] << 6; - CommandMailbox->Bytes[7] = LogicalDriveNumber; -} - -static inline -void DAC960_P_To_PD_TranslateReadWriteCommand(DAC960_V1_CommandMailbox_T - *CommandMailbox) -{ - int LogicalDriveNumber = CommandMailbox->Bytes[7]; - CommandMailbox->Bytes[7] = CommandMailbox->Bytes[3] >> 6; - CommandMailbox->Bytes[3] &= 0x7; - CommandMailbox->Bytes[3] |= LogicalDriveNumber << 3; -} - - -/* - Define prototypes for the forward referenced DAC960 Driver Internal Functions. -*/ - -static void DAC960_FinalizeController(DAC960_Controller_T *); -static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *); -static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *); -static void DAC960_RequestFunction(struct request_queue *); -static irqreturn_t DAC960_BA_InterruptHandler(int, void *); -static irqreturn_t DAC960_LP_InterruptHandler(int, void *); -static irqreturn_t DAC960_LA_InterruptHandler(int, void *); -static irqreturn_t DAC960_PG_InterruptHandler(int, void *); -static irqreturn_t DAC960_PD_InterruptHandler(int, void *); -static irqreturn_t DAC960_P_InterruptHandler(int, void *); -static void DAC960_V1_QueueMonitoringCommand(DAC960_Command_T *); -static void DAC960_V2_QueueMonitoringCommand(DAC960_Command_T *); -static void DAC960_MonitoringTimerFunction(struct timer_list *); -static void DAC960_Message(DAC960_MessageLevel_T, unsigned char *, - DAC960_Controller_T *, ...); -static void DAC960_CreateProcEntries(DAC960_Controller_T *); -static void DAC960_DestroyProcEntries(DAC960_Controller_T *); - -#endif /* DAC960_DriverVersion */ diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 8aec33277fda..20bb4bfa4be6 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -121,18 +121,6 @@ source "drivers/block/mtip32xx/Kconfig" source "drivers/block/zram/Kconfig" -config BLK_DEV_DAC960 - tristate "Mylex DAC960/DAC1100 PCI RAID Controller support" - depends on PCI - help - This driver adds support for the Mylex DAC960, AcceleRAID, and - eXtremeRAID PCI RAID controllers. See the file - for further information - about this driver. - - To compile this driver as a module, choose M here: the - module will be called DAC960. - config BLK_DEV_UMEM tristate "Micro Memory MM5415 Battery Backed RAM support" depends on PCI diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 8566b188368b..a53cc1e3a2d3 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -16,7 +16,6 @@ obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o obj-$(CONFIG_AMIGA_Z2RAM) += z2ram.o obj-$(CONFIG_BLK_DEV_RAM) += brd.o obj-$(CONFIG_BLK_DEV_LOOP) += loop.o -obj-$(CONFIG_BLK_DEV_DAC960) += DAC960.o obj-$(CONFIG_XILINX_SYSACE) += xsysace.o obj-$(CONFIG_CDROM_PKTCDVD) += pktcdvd.o obj-$(CONFIG_SUNVDC) += sunvdc.o -- cgit v1.2.3 From 138126214868a741691edec92d4c94d428213302 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 18 Oct 2018 15:15:11 +0200 Subject: skd: switch to the generic DMA API The PCI DMA API is deprecated, switch to the generic DMA API instead. Also make use of the dma_set_mask_and_coherent helper to easily set the streaming an coherent DMA masks together. Signed-off-by: Christoph Hellwig Signed-off-by: Jens Axboe --- drivers/block/skd_main.c | 63 +++++++++++++++++++----------------------------- 1 file changed, 25 insertions(+), 38 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/skd_main.c b/drivers/block/skd_main.c index 80a5806ede03..7c5fc6942f32 100644 --- a/drivers/block/skd_main.c +++ b/drivers/block/skd_main.c @@ -632,7 +632,7 @@ static bool skd_preop_sg_list(struct skd_device *skdev, * Map scatterlist to PCI bus addresses. * Note PCI might change the number of entries. */ - n_sg = pci_map_sg(skdev->pdev, sgl, n_sg, skreq->data_dir); + n_sg = dma_map_sg(&skdev->pdev->dev, sgl, n_sg, skreq->data_dir); if (n_sg <= 0) return false; @@ -682,7 +682,8 @@ static void skd_postop_sg_list(struct skd_device *skdev, skreq->sksg_list[skreq->n_sg - 1].next_desc_ptr = skreq->sksg_dma_address + ((skreq->n_sg) * sizeof(struct fit_sg_descriptor)); - pci_unmap_sg(skdev->pdev, &skreq->sg[0], skreq->n_sg, skreq->data_dir); + dma_unmap_sg(&skdev->pdev->dev, &skreq->sg[0], skreq->n_sg, + skreq->data_dir); } /* @@ -2632,8 +2633,8 @@ static int skd_cons_skcomp(struct skd_device *skdev) "comp pci_alloc, total bytes %zd entries %d\n", SKD_SKCOMP_SIZE, SKD_N_COMPLETION_ENTRY); - skcomp = pci_zalloc_consistent(skdev->pdev, SKD_SKCOMP_SIZE, - &skdev->cq_dma_address); + skcomp = dma_zalloc_coherent(&skdev->pdev->dev, SKD_SKCOMP_SIZE, + &skdev->cq_dma_address, GFP_KERNEL); if (skcomp == NULL) { rc = -ENOMEM; @@ -2674,10 +2675,10 @@ static int skd_cons_skmsg(struct skd_device *skdev) skmsg->id = i + SKD_ID_FIT_MSG; - skmsg->msg_buf = pci_alloc_consistent(skdev->pdev, - SKD_N_FITMSG_BYTES, - &skmsg->mb_dma_address); - + skmsg->msg_buf = dma_alloc_coherent(&skdev->pdev->dev, + SKD_N_FITMSG_BYTES, + &skmsg->mb_dma_address, + GFP_KERNEL); if (skmsg->msg_buf == NULL) { rc = -ENOMEM; goto err_out; @@ -2971,8 +2972,8 @@ err_out: static void skd_free_skcomp(struct skd_device *skdev) { if (skdev->skcomp_table) - pci_free_consistent(skdev->pdev, SKD_SKCOMP_SIZE, - skdev->skcomp_table, skdev->cq_dma_address); + dma_free_coherent(&skdev->pdev->dev, SKD_SKCOMP_SIZE, + skdev->skcomp_table, skdev->cq_dma_address); skdev->skcomp_table = NULL; skdev->cq_dma_address = 0; @@ -2991,8 +2992,8 @@ static void skd_free_skmsg(struct skd_device *skdev) skmsg = &skdev->skmsg_table[i]; if (skmsg->msg_buf != NULL) { - pci_free_consistent(skdev->pdev, SKD_N_FITMSG_BYTES, - skmsg->msg_buf, + dma_free_coherent(&skdev->pdev->dev, SKD_N_FITMSG_BYTES, + skmsg->msg_buf, skmsg->mb_dma_address); } skmsg->msg_buf = NULL; @@ -3172,18 +3173,12 @@ static int skd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) rc = pci_request_regions(pdev, DRV_NAME); if (rc) goto err_out; - rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); - if (!rc) { - if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) { - dev_err(&pdev->dev, "consistent DMA mask error %d\n", - rc); - } - } else { - rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (rc) { - dev_err(&pdev->dev, "DMA mask error %d\n", rc); - goto err_out_regions; - } + rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); + if (rc) + dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + if (rc) { + dev_err(&pdev->dev, "DMA mask error %d\n", rc); + goto err_out_regions; } if (!skd_major) { @@ -3367,20 +3362,12 @@ static int skd_pci_resume(struct pci_dev *pdev) rc = pci_request_regions(pdev, DRV_NAME); if (rc) goto err_out; - rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); - if (!rc) { - if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) { - - dev_err(&pdev->dev, "consistent DMA mask error %d\n", - rc); - } - } else { - rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (rc) { - - dev_err(&pdev->dev, "DMA mask error %d\n", rc); - goto err_out_regions; - } + rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); + if (rc) + dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + if (rc) { + dev_err(&pdev->dev, "DMA mask error %d\n", rc); + goto err_out_regions; } pci_set_master(pdev); -- cgit v1.2.3 From 64ab1fa5da058960fdd930b768c6c7b441d53d17 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 18 Oct 2018 15:15:12 +0200 Subject: sx8: remove dead IF_64BIT_DMA_IS_POSSIBLE code This code has effectively been commented out since the first commit, so remove it. Signed-off-by: Christoph Hellwig Signed-off-by: Jens Axboe --- drivers/block/sx8.c | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index 16f37254bcf4..377c17e106c3 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c @@ -197,7 +197,6 @@ enum { FL_NON_RAID = FW_VER_NON_RAID, FL_4PORT = FW_VER_4PORT, FL_FW_VER_MASK = (FW_VER_NON_RAID | FW_VER_4PORT), - FL_DAC = (1 << 16), FL_DYN_MAJOR = (1 << 17), }; @@ -1585,7 +1584,6 @@ static int carm_init_shm(struct carm_host *host) static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { struct carm_host *host; - unsigned int pci_dac; int rc; struct request_queue *q; unsigned int i; @@ -1600,28 +1598,12 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) goto err_out; -#ifdef IF_64BIT_DMA_IS_POSSIBLE /* grrrr... */ - rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); - if (!rc) { - rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); - if (rc) { - printk(KERN_ERR DRV_NAME "(%s): consistent DMA mask failure\n", - pci_name(pdev)); - goto err_out_regions; - } - pci_dac = 1; - } else { -#endif - rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (rc) { - printk(KERN_ERR DRV_NAME "(%s): DMA mask failure\n", - pci_name(pdev)); - goto err_out_regions; - } - pci_dac = 0; -#ifdef IF_64BIT_DMA_IS_POSSIBLE /* grrrr... */ + rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (rc) { + printk(KERN_ERR DRV_NAME "(%s): DMA mask failure\n", + pci_name(pdev)); + goto err_out_regions; } -#endif host = kzalloc(sizeof(*host), GFP_KERNEL); if (!host) { @@ -1632,7 +1614,6 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) } host->pdev = pdev; - host->flags = pci_dac ? FL_DAC : 0; spin_lock_init(&host->lock); INIT_WORK(&host->fsm_task, carm_fsm_task); init_completion(&host->probe_comp); -- cgit v1.2.3 From 931da2f7a56b7e84a75f40472edf96a5689734a7 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 18 Oct 2018 15:15:13 +0200 Subject: sx8: switch to the generic DMA API The PCI DMA API is deprecated, switch to the generic DMA API instead. Signed-off-by: Christoph Hellwig Signed-off-by: Jens Axboe --- drivers/block/sx8.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index 377c17e106c3..064b8c5c7a32 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c @@ -861,9 +861,9 @@ static blk_status_t carm_queue_rq(struct blk_mq_hw_ctx *hctx, if (rq_data_dir(rq) == WRITE) { writing = 1; - pci_dir = PCI_DMA_TODEVICE; + pci_dir = DMA_TO_DEVICE; } else { - pci_dir = PCI_DMA_FROMDEVICE; + pci_dir = DMA_FROM_DEVICE; } /* get scatterlist from block layer */ @@ -877,7 +877,7 @@ static blk_status_t carm_queue_rq(struct blk_mq_hw_ctx *hctx, } /* map scatterlist to PCI bus addresses */ - n_elem = pci_map_sg(host->pdev, sg, n_elem, pci_dir); + n_elem = dma_map_sg(&host->pdev->dev, sg, n_elem, pci_dir); if (n_elem <= 0) { /* request with no s/g entries? */ carm_end_rq(host, crq, BLK_STS_IOERR); @@ -1058,11 +1058,11 @@ static inline void carm_handle_rw(struct carm_host *host, VPRINTK("ENTER\n"); if (rq_data_dir(crq->rq) == WRITE) - pci_dir = PCI_DMA_TODEVICE; + pci_dir = DMA_TO_DEVICE; else - pci_dir = PCI_DMA_FROMDEVICE; + pci_dir = DMA_FROM_DEVICE; - pci_unmap_sg(host->pdev, &crq->sg[0], crq->n_elem, pci_dir); + dma_unmap_sg(&host->pdev->dev, &crq->sg[0], crq->n_elem, pci_dir); carm_end_rq(host, crq, error); } @@ -1567,8 +1567,8 @@ static void carm_free_disks(struct carm_host *host) static int carm_init_shm(struct carm_host *host) { - host->shm = pci_alloc_consistent(host->pdev, CARM_SHM_SIZE, - &host->shm_dma); + host->shm = dma_alloc_coherent(&host->pdev->dev, CARM_SHM_SIZE, + &host->shm_dma, GFP_KERNEL); if (!host->shm) return -ENOMEM; @@ -1598,7 +1598,7 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) goto err_out; - rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); if (rc) { printk(KERN_ERR DRV_NAME "(%s): DMA mask failure\n", pci_name(pdev)); @@ -1643,7 +1643,7 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) printk(KERN_ERR DRV_NAME "(%s): OOB queue alloc failure\n", pci_name(pdev)); rc = PTR_ERR(q); - goto err_out_pci_free; + goto err_out_dma_free; } host->oob_q = q; q->queuedata = host; @@ -1708,8 +1708,8 @@ err_out_free_majors: clear_bit(1, &carm_major_alloc); blk_cleanup_queue(host->oob_q); blk_mq_free_tag_set(&host->tag_set); -err_out_pci_free: - pci_free_consistent(pdev, CARM_SHM_SIZE, host->shm, host->shm_dma); +err_out_dma_free: + dma_free_coherent(&pdev->dev, CARM_SHM_SIZE, host->shm, host->shm_dma); err_out_iounmap: iounmap(host->mmio); err_out_kfree: @@ -1740,7 +1740,7 @@ static void carm_remove_one (struct pci_dev *pdev) clear_bit(1, &carm_major_alloc); blk_cleanup_queue(host->oob_q); blk_mq_free_tag_set(&host->tag_set); - pci_free_consistent(pdev, CARM_SHM_SIZE, host->shm, host->shm_dma); + dma_free_coherent(&pdev->dev, CARM_SHM_SIZE, host->shm, host->shm_dma); iounmap(host->mmio); kfree(host); pci_release_regions(pdev); -- cgit v1.2.3 From b46d40daba968f6bac901b50e8fbc016b9c18c00 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 18 Oct 2018 15:15:14 +0200 Subject: umem: switch to the generic DMA API The PCI DMA API is deprecated, switch to the generic DMA API instead. Signed-off-by: Christoph Hellwig Signed-off-by: Jens Axboe --- drivers/block/umem.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/umem.c b/drivers/block/umem.c index 9094ca60949c..be3e3ab79950 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c @@ -363,12 +363,12 @@ static int add_bio(struct cardinfo *card) vec = bio_iter_iovec(bio, card->current_iter); - dma_handle = pci_map_page(card->dev, + dma_handle = dma_map_page(&card->dev->dev, vec.bv_page, vec.bv_offset, vec.bv_len, bio_op(bio) == REQ_OP_READ ? - PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); + DMA_FROM_DEVICE : DMA_TO_DEVICE); p = &card->mm_pages[card->Ready]; desc = &p->desc[p->cnt]; @@ -448,10 +448,10 @@ static void process_page(unsigned long data) page->iter = page->bio->bi_iter; } - pci_unmap_page(card->dev, desc->data_dma_handle, + dma_unmap_page(&card->dev->dev, desc->data_dma_handle, vec.bv_len, (control & DMASCR_TRANSFER_READ) ? - PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); + DMA_TO_DEVICE : DMA_FROM_DEVICE); if (control & DMASCR_HARD_ERROR) { /* error */ bio->bi_status = BLK_STS_IOERR; @@ -817,8 +817,8 @@ static int mm_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) dev_printk(KERN_INFO, &dev->dev, "Micro Memory(tm) controller found (PCI Mem Module (Battery Backup))\n"); - if (pci_set_dma_mask(dev, DMA_BIT_MASK(64)) && - pci_set_dma_mask(dev, DMA_BIT_MASK(32))) { + if (dma_set_mask(&dev->dev, DMA_BIT_MASK(64)) && + dma_set_mask(&dev->dev, DMA_BIT_MASK(32))) { dev_printk(KERN_WARNING, &dev->dev, "NO suitable DMA found\n"); return -ENOMEM; } @@ -871,12 +871,10 @@ static int mm_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) goto failed_magic; } - card->mm_pages[0].desc = pci_alloc_consistent(card->dev, - PAGE_SIZE * 2, - &card->mm_pages[0].page_dma); - card->mm_pages[1].desc = pci_alloc_consistent(card->dev, - PAGE_SIZE * 2, - &card->mm_pages[1].page_dma); + card->mm_pages[0].desc = dma_alloc_coherent(&card->dev->dev, + PAGE_SIZE * 2, &card->mm_pages[0].page_dma, GFP_KERNEL); + card->mm_pages[1].desc = dma_alloc_coherent(&card->dev->dev, + PAGE_SIZE * 2, &card->mm_pages[1].page_dma, GFP_KERNEL); if (card->mm_pages[0].desc == NULL || card->mm_pages[1].desc == NULL) { dev_printk(KERN_ERR, &card->dev->dev, "alloc failed\n"); @@ -1002,13 +1000,13 @@ static int mm_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) failed_req_irq: failed_alloc: if (card->mm_pages[0].desc) - pci_free_consistent(card->dev, PAGE_SIZE*2, - card->mm_pages[0].desc, - card->mm_pages[0].page_dma); + dma_free_coherent(&card->dev->dev, PAGE_SIZE * 2, + card->mm_pages[0].desc, + card->mm_pages[0].page_dma); if (card->mm_pages[1].desc) - pci_free_consistent(card->dev, PAGE_SIZE*2, - card->mm_pages[1].desc, - card->mm_pages[1].page_dma); + dma_free_coherent(&card->dev->dev, PAGE_SIZE * 2, + card->mm_pages[1].desc, + card->mm_pages[1].page_dma); failed_magic: iounmap(card->csr_remap); failed_remap_csr: @@ -1027,11 +1025,11 @@ static void mm_pci_remove(struct pci_dev *dev) iounmap(card->csr_remap); if (card->mm_pages[0].desc) - pci_free_consistent(card->dev, PAGE_SIZE*2, + dma_free_coherent(&card->dev->dev, PAGE_SIZE * 2, card->mm_pages[0].desc, card->mm_pages[0].page_dma); if (card->mm_pages[1].desc) - pci_free_consistent(card->dev, PAGE_SIZE*2, + dma_free_coherent(&card->dev->dev, PAGE_SIZE * 2, card->mm_pages[1].desc, card->mm_pages[1].page_dma); blk_cleanup_queue(card->queue); -- cgit v1.2.3 From 77a12e51fcf8c6200818e29fe1e90d944bb1af4a Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 18 Oct 2018 15:15:15 +0200 Subject: rsxx: switch to the generic DMA API The PCI DMA API is deprecated, switch to the generic DMA API instead. Signed-off-by: Christoph Hellwig Signed-off-by: Jens Axboe --- drivers/block/rsxx/core.c | 2 +- drivers/block/rsxx/dma.c | 52 +++++++++++++++++++++++------------------------ 2 files changed, 27 insertions(+), 27 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/rsxx/core.c b/drivers/block/rsxx/core.c index f2c631ce793c..639051502181 100644 --- a/drivers/block/rsxx/core.c +++ b/drivers/block/rsxx/core.c @@ -782,7 +782,7 @@ static int rsxx_pci_probe(struct pci_dev *dev, pci_set_master(dev); pci_set_dma_max_seg_size(dev, RSXX_HW_BLK_SIZE); - st = pci_set_dma_mask(dev, DMA_BIT_MASK(64)); + st = dma_set_mask(&dev->dev, DMA_BIT_MASK(64)); if (st) { dev_err(CARD_TO_DEV(card), "No usable DMA configuration,aborting\n"); diff --git a/drivers/block/rsxx/dma.c b/drivers/block/rsxx/dma.c index 8fbc1bf6db3d..af9cf0215164 100644 --- a/drivers/block/rsxx/dma.c +++ b/drivers/block/rsxx/dma.c @@ -224,12 +224,12 @@ static void dma_intr_coal_auto_tune(struct rsxx_cardinfo *card) static void rsxx_free_dma(struct rsxx_dma_ctrl *ctrl, struct rsxx_dma *dma) { if (dma->cmd != HW_CMD_BLK_DISCARD) { - if (!pci_dma_mapping_error(ctrl->card->dev, dma->dma_addr)) { - pci_unmap_page(ctrl->card->dev, dma->dma_addr, + if (!dma_mapping_error(&ctrl->card->dev->dev, dma->dma_addr)) { + dma_unmap_page(&ctrl->card->dev->dev, dma->dma_addr, get_dma_size(dma), dma->cmd == HW_CMD_BLK_WRITE ? - PCI_DMA_TODEVICE : - PCI_DMA_FROMDEVICE); + DMA_TO_DEVICE : + DMA_FROM_DEVICE); } } @@ -438,23 +438,23 @@ static void rsxx_issue_dmas(struct rsxx_dma_ctrl *ctrl) if (dma->cmd != HW_CMD_BLK_DISCARD) { if (dma->cmd == HW_CMD_BLK_WRITE) - dir = PCI_DMA_TODEVICE; + dir = DMA_TO_DEVICE; else - dir = PCI_DMA_FROMDEVICE; + dir = DMA_FROM_DEVICE; /* - * The function pci_map_page is placed here because we + * The function dma_map_page is placed here because we * can only, by design, issue up to 255 commands to the * hardware at one time per DMA channel. So the maximum * amount of mapped memory would be 255 * 4 channels * * 4096 Bytes which is less than 2GB, the limit of a x8 - * Non-HWWD PCIe slot. This way the pci_map_page + * Non-HWWD PCIe slot. This way the dma_map_page * function should never fail because of a lack of * mappable memory. */ - dma->dma_addr = pci_map_page(ctrl->card->dev, dma->page, + dma->dma_addr = dma_map_page(&ctrl->card->dev->dev, dma->page, dma->pg_off, dma->sub_page.cnt << 9, dir); - if (pci_dma_mapping_error(ctrl->card->dev, dma->dma_addr)) { + if (dma_mapping_error(&ctrl->card->dev->dev, dma->dma_addr)) { push_tracker(ctrl->trackers, tag); rsxx_complete_dma(ctrl, dma, DMA_CANCELLED); continue; @@ -776,10 +776,10 @@ bvec_err: /*----------------- DMA Engine Initialization & Setup -------------------*/ int rsxx_hw_buffers_init(struct pci_dev *dev, struct rsxx_dma_ctrl *ctrl) { - ctrl->status.buf = pci_alloc_consistent(dev, STATUS_BUFFER_SIZE8, - &ctrl->status.dma_addr); - ctrl->cmd.buf = pci_alloc_consistent(dev, COMMAND_BUFFER_SIZE8, - &ctrl->cmd.dma_addr); + ctrl->status.buf = dma_alloc_coherent(&dev->dev, STATUS_BUFFER_SIZE8, + &ctrl->status.dma_addr, GFP_KERNEL); + ctrl->cmd.buf = dma_alloc_coherent(&dev->dev, COMMAND_BUFFER_SIZE8, + &ctrl->cmd.dma_addr, GFP_KERNEL); if (ctrl->status.buf == NULL || ctrl->cmd.buf == NULL) return -ENOMEM; @@ -962,12 +962,12 @@ failed_dma_setup: vfree(ctrl->trackers); if (ctrl->status.buf) - pci_free_consistent(card->dev, STATUS_BUFFER_SIZE8, - ctrl->status.buf, - ctrl->status.dma_addr); + dma_free_coherent(&card->dev->dev, STATUS_BUFFER_SIZE8, + ctrl->status.buf, + ctrl->status.dma_addr); if (ctrl->cmd.buf) - pci_free_consistent(card->dev, COMMAND_BUFFER_SIZE8, - ctrl->cmd.buf, ctrl->cmd.dma_addr); + dma_free_coherent(&card->dev->dev, COMMAND_BUFFER_SIZE8, + ctrl->cmd.buf, ctrl->cmd.dma_addr); } return st; @@ -1023,10 +1023,10 @@ void rsxx_dma_destroy(struct rsxx_cardinfo *card) vfree(ctrl->trackers); - pci_free_consistent(card->dev, STATUS_BUFFER_SIZE8, - ctrl->status.buf, ctrl->status.dma_addr); - pci_free_consistent(card->dev, COMMAND_BUFFER_SIZE8, - ctrl->cmd.buf, ctrl->cmd.dma_addr); + dma_free_coherent(&card->dev->dev, STATUS_BUFFER_SIZE8, + ctrl->status.buf, ctrl->status.dma_addr); + dma_free_coherent(&card->dev->dev, COMMAND_BUFFER_SIZE8, + ctrl->cmd.buf, ctrl->cmd.dma_addr); } } @@ -1059,11 +1059,11 @@ int rsxx_eeh_save_issued_dmas(struct rsxx_cardinfo *card) card->ctrl[i].stats.reads_issued--; if (dma->cmd != HW_CMD_BLK_DISCARD) { - pci_unmap_page(card->dev, dma->dma_addr, + dma_unmap_page(&card->dev->dev, dma->dma_addr, get_dma_size(dma), dma->cmd == HW_CMD_BLK_WRITE ? - PCI_DMA_TODEVICE : - PCI_DMA_FROMDEVICE); + DMA_TO_DEVICE : + DMA_FROM_DEVICE); } list_add_tail(&dma->list, &issued_dmas[i]); -- cgit v1.2.3 From ee75fa2ae0e23f575630923bc598e7dedbb8b21c Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 18 Oct 2018 15:15:16 +0200 Subject: mtip32xx: fully switch to the generic DMA API The mtip32xx used an odd mix of the old PCI and the generic DMA API, so switch it over to the generic API entirely. Note that this also removes a weird fallback to just a 32-bit coherent dma mask if the 64-bit dma mask doesn't work, as that can't even happen. Reviewed-by: Johannes Thumshirn Signed-off-by: Christoph Hellwig Signed-off-by: Jens Axboe --- drivers/block/mtip32xx/mtip32xx.c | 47 +++++++++++++++------------------------ 1 file changed, 18 insertions(+), 29 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 1d7d48d8a205..dfc8de6ce525 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -1862,11 +1862,9 @@ static int exec_drive_taskfile(struct driver_data *dd, if (IS_ERR(outbuf)) return PTR_ERR(outbuf); - outbuf_dma = pci_map_single(dd->pdev, - outbuf, - taskout, - DMA_TO_DEVICE); - if (pci_dma_mapping_error(dd->pdev, outbuf_dma)) { + outbuf_dma = dma_map_single(&dd->pdev->dev, outbuf, + taskout, DMA_TO_DEVICE); + if (dma_mapping_error(&dd->pdev->dev, outbuf_dma)) { err = -ENOMEM; goto abort; } @@ -1880,10 +1878,9 @@ static int exec_drive_taskfile(struct driver_data *dd, inbuf = NULL; goto abort; } - inbuf_dma = pci_map_single(dd->pdev, - inbuf, - taskin, DMA_FROM_DEVICE); - if (pci_dma_mapping_error(dd->pdev, inbuf_dma)) { + inbuf_dma = dma_map_single(&dd->pdev->dev, inbuf, + taskin, DMA_FROM_DEVICE); + if (dma_mapping_error(&dd->pdev->dev, inbuf_dma)) { err = -ENOMEM; goto abort; } @@ -2002,11 +1999,11 @@ static int exec_drive_taskfile(struct driver_data *dd, /* reclaim the DMA buffers.*/ if (inbuf_dma) - pci_unmap_single(dd->pdev, inbuf_dma, - taskin, DMA_FROM_DEVICE); + dma_unmap_single(&dd->pdev->dev, inbuf_dma, taskin, + DMA_FROM_DEVICE); if (outbuf_dma) - pci_unmap_single(dd->pdev, outbuf_dma, - taskout, DMA_TO_DEVICE); + dma_unmap_single(&dd->pdev->dev, outbuf_dma, taskout, + DMA_TO_DEVICE); inbuf_dma = 0; outbuf_dma = 0; @@ -2053,11 +2050,11 @@ static int exec_drive_taskfile(struct driver_data *dd, } abort: if (inbuf_dma) - pci_unmap_single(dd->pdev, inbuf_dma, - taskin, DMA_FROM_DEVICE); + dma_unmap_single(&dd->pdev->dev, inbuf_dma, taskin, + DMA_FROM_DEVICE); if (outbuf_dma) - pci_unmap_single(dd->pdev, outbuf_dma, - taskout, DMA_TO_DEVICE); + dma_unmap_single(&dd->pdev->dev, outbuf_dma, taskout, + DMA_TO_DEVICE); kfree(outbuf); kfree(inbuf); @@ -4216,18 +4213,10 @@ static int mtip_pci_probe(struct pci_dev *pdev, goto iomap_err; } - if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { - rv = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); - - if (rv) { - rv = pci_set_consistent_dma_mask(pdev, - DMA_BIT_MASK(32)); - if (rv) { - dev_warn(&pdev->dev, - "64-bit DMA enable failed\n"); - goto setmask_err; - } - } + rv = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); + if (rv) { + dev_warn(&pdev->dev, "64-bit DMA enable failed\n"); + goto setmask_err; } /* Copy the info we may need later into the private data structure. */ -- cgit v1.2.3